From 65bf9ad4152a63e8c231cdd3a10bdbb22d5f6a55 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Wed, 25 Aug 2021 14:12:09 -0700 Subject: [PATCH] channel: Remove the Sender and Receiver types. The distinction between sender and receiver is not carrying its weight in the public API for this package. Move unexported safety-check wrappers into the top-level package and collapse the methods back into the Channel type. --- base.go | 9 +++++++-- channel/channel_test.go | 2 +- channel/doc.go | 23 +++++++---------------- client.go | 2 +- server.go | 6 +++--- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/base.go b/base.go index 8be3b23..db9cb6e 100644 --- a/base.go +++ b/base.go @@ -7,7 +7,6 @@ import ( "fmt" "strings" - "github.com/creachadair/jrpc2/channel" "github.com/creachadair/jrpc2/code" ) @@ -389,8 +388,14 @@ func fixID(id json.RawMessage) json.RawMessage { return nil } +// sender is the subset of channel.Channel needed to send messages. +type sender interface{ Send([]byte) error } + +// receiver is the subset of channel.Channel needed to receive messages. +type receiver interface{ Recv() ([]byte, error) } + // encode marshals rsps as JSON and forwards it to the channel. -func encode(ch channel.Sender, rsps jmessages) (int, error) { +func encode(ch sender, rsps jmessages) (int, error) { bits, err := rsps.toJSON() if err != nil { return 0, err diff --git a/channel/channel_test.go b/channel/channel_test.go index b04788d..755b380 100644 --- a/channel/channel_test.go +++ b/channel/channel_test.go @@ -20,7 +20,7 @@ func newPipe(framing Framing) (client, server Channel) { return } -func testSendRecv(t *testing.T, s Sender, r Receiver, msg string) { +func testSendRecv(t *testing.T, s, r Channel, msg string) { var wg sync.WaitGroup var sendErr, recvErr error var data []byte diff --git a/channel/doc.go b/channel/doc.go index cff4d6a..a413df9 100644 --- a/channel/doc.go +++ b/channel/doc.go @@ -33,30 +33,21 @@ package channel import "strings" -// A Sender represents the ability to transmit a message on a channel. -type Sender interface { +// A Channel represents the ability to transmit and receive data records. A +// channel does not interpret the contents of a record, but may add and remove +// framing so that records can be embedded in higher-level protocols. +// +// One sender and one receiver may use a Channel concurrently, but the methods +// of a Channel are not otherwise required to be safe for concurrent use. +type Channel interface { // Send transmits a record on the channel. Each call to Send transmits one // complete record. Send([]byte) error -} -// A Receiver represents the ability to receive a message from a channel. -type Receiver interface { // Recv returns the next available record from the channel. If no further // messages are available, it returns nil, io.EOF. Each call to Recv // fetches a single complete record. Recv() ([]byte, error) -} - -// A Channel represents the ability to transmit and receive data records. A -// channel does not interpret the contents of a record, but may add and remove -// framing so that records can be embedded in higher-level protocols. -// -// One sender and one receiver may use a Channel concurrently, but the methods -// of a Channel are not otherwise required to be safe for concurrent use. -type Channel interface { - Sender - Receiver // Close shuts down the channel, after which no further records may be // sent or received. diff --git a/client.go b/client.go index 54c4ce3..c9e217f 100644 --- a/client.go +++ b/client.go @@ -69,7 +69,7 @@ func NewClient(ch channel.Channel, opts *ClientOptions) *Client { // accept receives the next batch of responses from the server. This may // either be a list or a single object, the decoder for jmessages knows how to // handle both. The caller must not hold c.mu. -func (c *Client) accept(ch channel.Receiver) error { +func (c *Client) accept(ch receiver) error { var in jmessages bits, err := ch.Recv() if err == nil { diff --git a/server.go b/server.go index b63cf64..ffb3d89 100644 --- a/server.go +++ b/server.go @@ -200,7 +200,7 @@ func (s *Server) waitForBarrier(n int) { // completed, to ensure that notifications are processed in a partial order // that respects order of receipt. Notifications within a batch are handled // concurrently. -func (s *Server) dispatch(next jmessages, ch channel.Sender) func() error { +func (s *Server) dispatch(next jmessages, ch sender) func() error { // Resolve all the task handlers or record errors. start := time.Now() tasks := s.checkAndAssign(next) @@ -240,7 +240,7 @@ func (s *Server) dispatch(next jmessages, ch channel.Sender) func() error { // deliver cleans up completed responses and arranges their replies (if any) to // be sent back to the client. -func (s *Server) deliver(rsps jmessages, ch channel.Sender, elapsed time.Duration) error { +func (s *Server) deliver(rsps jmessages, ch sender, elapsed time.Duration) error { if len(rsps) == 0 { return nil } @@ -563,7 +563,7 @@ func (s *Server) stop(err error) { // them to the queue. Decoding errors and message-format problems are handled // and reported back to the client directly, so that any message that survives // into the request queue is structurally valid. -func (s *Server) read(ch channel.Receiver) { +func (s *Server) read(ch receiver) { for { // If the message is not sensible, report an error; otherwise enqueue it // for processing. Errors in individual requests are handled later.