type Pipeline … // Next returns the next id for a request/response pair. func (p *Pipeline) Next() uint { … } // StartRequest blocks until it is time to send (or, if this is a server, receive) // the request with the given id. func (p *Pipeline) StartRequest(id uint) { … } // EndRequest notifies p that the request with the given id has been sent // (or, if this is a server, received). func (p *Pipeline) EndRequest(id uint) { … } // StartResponse blocks until it is time to receive (or, if this is a server, send) // the request with the given id. func (p *Pipeline) StartResponse(id uint) { … } // EndResponse notifies p that the response with the given id has been received // (or, if this is a server, sent). func (p *Pipeline) EndResponse(id uint) { … } type sequencer … // Start waits until it is time for the event numbered id to begin. // That is, except for the first event, it waits until End(id-1) has // been called. func (s *sequencer) Start(id uint) { … } // End notifies the sequencer that the event numbered id has completed, // allowing it to schedule the event numbered id+1. It is a run-time error // to call End with an id that is not the number of the active event. func (s *sequencer) End(id uint) { … }