Add explicit channel direction information

This commit adds explicit input and output channel type information to
make the channel's intent visible to developers.
This commit is contained in:
Jan Dittberner 2022-12-04 13:47:51 +01:00
parent 46407b3685
commit 7852c4d3df
5 changed files with 67 additions and 52 deletions

View file

@ -174,7 +174,7 @@ type ClientHandler struct {
caList []string
}
func (c *ClientHandler) Send(ctx context.Context, command *protocol.Command, out chan []byte) error {
func (c *ClientHandler) Send(ctx context.Context, command *protocol.Command, out chan<- []byte) error {
var (
frame []byte
err error
@ -213,7 +213,7 @@ func (c *ClientHandler) Send(ctx context.Context, command *protocol.Command, out
return nil
}
func (c *ClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte) (*protocol.Response, error) {
func (c *ClientHandler) ResponseAnnounce(ctx context.Context, in <-chan []byte) (*protocol.Response, error) {
response := &protocol.Response{}
var announce messages.ResponseAnnounce
@ -236,7 +236,7 @@ func (c *ClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte) (*
}
}
func (c *ClientHandler) ResponseData(ctx context.Context, in chan []byte, response *protocol.Response) error {
func (c *ClientHandler) ResponseData(ctx context.Context, in <-chan []byte, response *protocol.Response) error {
select {
case <-ctx.Done():
return nil

View file

@ -116,18 +116,19 @@ func main() {
logger.WithError(err).Fatal("could not setup serial link handler")
}
defer func() { _ = serialHandler.Close() }()
logger.Info("setup complete, starting signer operation")
if err = runSigner(logger, serialHandler); err != nil {
logger.WithError(err).Fatal("error running serial handler")
logger.WithError(err).Error("error running serial handler")
os.Exit(1)
}
}
func runSigner(logger *logrus.Logger, serialHandler *serial.Handler) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
defer func() { _ = serialHandler.Close() }()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)

View file

@ -46,7 +46,7 @@ type MsgPackHandler struct {
fetchCRLHandler *revoking.FetchCRLHandler
}
func (m *MsgPackHandler) CommandAnnounce(ctx context.Context, frames chan []byte) (*protocol.Command, error) {
func (m *MsgPackHandler) CommandAnnounce(ctx context.Context, frames <-chan []byte) (*protocol.Command, error) {
select {
case <-ctx.Done():
return nil, nil
@ -67,7 +67,7 @@ func (m *MsgPackHandler) CommandAnnounce(ctx context.Context, frames chan []byte
}
}
func (m *MsgPackHandler) CommandData(ctx context.Context, frames chan []byte, command *protocol.Command) error {
func (m *MsgPackHandler) CommandData(ctx context.Context, frames <-chan []byte, command *protocol.Command) error {
select {
case <-ctx.Done():
return nil
@ -106,7 +106,7 @@ func (m *MsgPackHandler) logCommandResponse(command *protocol.Command, response
m.logger.WithField("command", command).WithField("response", response).Debug("command and response")
}
func (m *MsgPackHandler) Respond(ctx context.Context, response *protocol.Response, out chan []byte) error {
func (m *MsgPackHandler) Respond(ctx context.Context, response *protocol.Response, out chan<- []byte) error {
announce, err := msgpack.Marshal(response.Announce)
if err != nil {
return fmt.Errorf("could not marshal response announcement: %w", err)

View file

@ -55,19 +55,19 @@ func (r *Response) String() string {
// ServerHandler is responsible for parsing incoming frames and calling commands
type ServerHandler interface {
// CommandAnnounce handles the initial announcement of a command.
CommandAnnounce(context.Context, chan []byte) (*Command, error)
CommandAnnounce(context.Context, <-chan []byte) (*Command, error)
// CommandData handles the command data.
CommandData(context.Context, chan []byte, *Command) error
CommandData(context.Context, <-chan []byte, *Command) error
// HandleCommand executes the command, generating a response.
HandleCommand(context.Context, *Command) (*Response, error)
// Respond generates the response for a command.
Respond(context.Context, *Response, chan []byte) error
Respond(context.Context, *Response, chan<- []byte) error
}
type ClientHandler interface {
Send(context.Context, *Command, chan []byte) error
ResponseAnnounce(context.Context, chan []byte) (*Response, error)
ResponseData(context.Context, chan []byte, *Response) error
Send(context.Context, *Command, chan<- []byte) error
ResponseAnnounce(context.Context, <-chan []byte) (*Response, error)
ResponseData(context.Context, <-chan []byte, *Response) error
HandleResponse(context.Context, *Response) error
}
@ -113,7 +113,8 @@ func (p protocolState) String() string {
type ServerProtocol struct {
handler ServerHandler
in, out chan []byte
in <-chan []byte
out chan<- []byte
logger *logrus.Logger
state protocolState
}
@ -229,7 +230,7 @@ func (p *ServerProtocol) respond(ctx context.Context, response *Response) error
return nil
}
func NewServer(handler ServerHandler, in, out chan []byte, logger *logrus.Logger) *ServerProtocol {
func NewServer(handler ServerHandler, in <-chan []byte, out chan<- []byte, logger *logrus.Logger) *ServerProtocol {
return &ServerProtocol{
handler: handler,
in: in,
@ -241,8 +242,9 @@ func NewServer(handler ServerHandler, in, out chan []byte, logger *logrus.Logger
type ClientProtocol struct {
handler ClientHandler
commands chan *Command
in, out chan []byte
commands <-chan *Command
in <-chan []byte
out chan<- []byte
logger *logrus.Logger
state protocolState
}
@ -289,8 +291,8 @@ func (p *ClientProtocol) cmdAnnounce(ctx context.Context) error {
select {
case <-ctx.Done():
return nil
case command := <-p.commands:
if command == nil {
case command, ok := <-p.commands:
if !ok {
return errCommandExpected
}
@ -300,6 +302,11 @@ func (p *ClientProtocol) cmdAnnounce(ctx context.Context) error {
return nil
}
p.logger.WithFields(map[string]interface{}{
"command": command.Announce,
"buffer length": len(p.commands),
}).Trace("handled command")
}
p.state = respAnnounce
@ -366,8 +373,9 @@ func (p *ClientProtocol) handleResponse(ctx context.Context, response *Response)
func NewClient(
handler ClientHandler,
commands chan *Command,
in, out chan []byte,
commands <-chan *Command,
in <-chan []byte,
out chan<- []byte,
logger *logrus.Logger,
) *ClientProtocol {
return &ClientProtocol{
@ -383,9 +391,9 @@ func NewClient(
// Framer handles bytes on the wire by adding or removing framing information.
type Framer interface {
// ReadFrames reads data frames and publishes unframed data to the channel.
ReadFrames(context.Context, io.Reader, chan []byte) error
ReadFrames(context.Context, io.Reader, chan<- []byte) error
// WriteFrames takes data from the channel and writes framed data to the writer.
WriteFrames(context.Context, io.Writer, chan []byte) error
WriteFrames(context.Context, io.Writer, <-chan []byte) error
}
const bufferSize = 1024
@ -408,7 +416,7 @@ func NewCOBSFramer(logger *logrus.Logger) (*COBSFramer, error) {
}, nil
}
func (c *COBSFramer) ReadFrames(ctx context.Context, reader io.Reader, frameChan chan []byte) error {
func (c *COBSFramer) ReadFrames(ctx context.Context, reader io.Reader, frameChan chan<- []byte) error {
var (
err error
raw, data, frame []byte
@ -496,7 +504,7 @@ func (c *COBSFramer) readRaw(ctx context.Context, reader io.Reader) ([]byte, err
}
}
func (c *COBSFramer) WriteFrames(ctx context.Context, writer io.Writer, frameChan chan []byte) error {
func (c *COBSFramer) WriteFrames(ctx context.Context, writer io.Writer, frameChan <-chan []byte) error {
for {
select {
case <-ctx.Done():

View file

@ -123,11 +123,11 @@ func TestProtocolState_String(t *testing.T) {
type noopServerHandler struct{}
func (h *noopServerHandler) CommandAnnounce(context.Context, chan []byte) (*Command, error) {
func (h *noopServerHandler) CommandAnnounce(context.Context, <-chan []byte) (*Command, error) {
return nil, nil
}
func (h *noopServerHandler) CommandData(context.Context, chan []byte, *Command) error {
func (h *noopServerHandler) CommandData(context.Context, <-chan []byte, *Command) error {
return nil
}
@ -135,7 +135,7 @@ func (h *noopServerHandler) HandleCommand(context.Context, *Command) (*Response,
return nil, nil
}
func (h *noopServerHandler) Respond(context.Context, *Response, chan []byte) error {
func (h *noopServerHandler) Respond(context.Context, *Response, chan<- []byte) error {
return nil
}
@ -143,7 +143,7 @@ type testServerHandler struct {
logger *logrus.Logger
}
func (h *testServerHandler) CommandAnnounce(ctx context.Context, in chan []byte) (*Command, error) {
func (h *testServerHandler) CommandAnnounce(ctx context.Context, in <-chan []byte) (*Command, error) {
select {
case <-ctx.Done():
return nil, nil
@ -154,7 +154,7 @@ func (h *testServerHandler) CommandAnnounce(ctx context.Context, in chan []byte)
}
}
func (h *testServerHandler) CommandData(ctx context.Context, in chan []byte, command *Command) error {
func (h *testServerHandler) CommandData(ctx context.Context, in <-chan []byte, command *Command) error {
select {
case <-ctx.Done():
return nil
@ -176,7 +176,7 @@ func (h *testServerHandler) HandleCommand(_ context.Context, command *Command) (
}, nil
}
func (h *testServerHandler) Respond(ctx context.Context, response *Response, out chan []byte) error {
func (h *testServerHandler) Respond(ctx context.Context, response *Response, out chan<- []byte) error {
h.logger.Info("send response")
buf := bytes.NewBuffer([]byte("test-response-"))
@ -192,7 +192,7 @@ func (h *testServerHandler) Respond(ctx context.Context, response *Response, out
type commandAnnounceErrServerHandler struct{ testServerHandler }
func (h *commandAnnounceErrServerHandler) CommandAnnounce(ctx context.Context, in chan []byte) (*Command, error) {
func (h *commandAnnounceErrServerHandler) CommandAnnounce(ctx context.Context, in <-chan []byte) (*Command, error) {
select {
case <-ctx.Done():
return nil, nil
@ -203,7 +203,7 @@ func (h *commandAnnounceErrServerHandler) CommandAnnounce(ctx context.Context, i
type commandAnnounceNilServerHandler struct{ testServerHandler }
func (h *commandAnnounceNilServerHandler) CommandAnnounce(ctx context.Context, in chan []byte) (*Command, error) {
func (h *commandAnnounceNilServerHandler) CommandAnnounce(ctx context.Context, in <-chan []byte) (*Command, error) {
select {
case <-ctx.Done():
return nil, nil
@ -214,7 +214,7 @@ func (h *commandAnnounceNilServerHandler) CommandAnnounce(ctx context.Context, i
type commandDataErrServerHandler struct{ testServerHandler }
func (h *commandDataErrServerHandler) CommandData(ctx context.Context, in chan []byte, _ *Command) error {
func (h *commandDataErrServerHandler) CommandData(ctx context.Context, in <-chan []byte, _ *Command) error {
select {
case <-ctx.Done():
return nil
@ -226,8 +226,7 @@ func (h *commandDataErrServerHandler) CommandData(ctx context.Context, in chan [
type commandDataNilAnnouncementServerHandler struct{ testServerHandler }
func (h *commandDataNilAnnouncementServerHandler) CommandAnnounce(
ctx context.Context,
in chan []byte,
ctx context.Context, in <-chan []byte,
) (*Command, error) {
select {
case <-ctx.Done():
@ -245,7 +244,7 @@ func (h *handleCommandErrServerHandler) HandleCommand(_ context.Context, command
type handleCommandNilCommandServerHandler struct{ testServerHandler }
func (h *handleCommandNilCommandServerHandler) CommandData(ctx context.Context, in chan []byte, _ *Command) error {
func (h *handleCommandNilCommandServerHandler) CommandData(ctx context.Context, in <-chan []byte, _ *Command) error {
select {
case <-ctx.Done():
return nil
@ -256,7 +255,7 @@ func (h *handleCommandNilCommandServerHandler) CommandData(ctx context.Context,
type respondErrServerHandler struct{ testServerHandler }
func (h *respondErrServerHandler) Respond(_ context.Context, r *Response, _ chan []byte) error {
func (h *respondErrServerHandler) Respond(_ context.Context, r *Response, _ chan<- []byte) error {
return fmt.Errorf("failed to respond %s", r)
}
@ -914,15 +913,15 @@ func readServerResponse(ctx context.Context, out chan []byte) []byte {
type noopClientHandler struct{}
func (h *noopClientHandler) Send(context.Context, *Command, chan []byte) error {
func (h *noopClientHandler) Send(context.Context, *Command, chan<- []byte) error {
return nil
}
func (h *noopClientHandler) ResponseAnnounce(context.Context, chan []byte) (*Response, error) {
func (h *noopClientHandler) ResponseAnnounce(context.Context, <-chan []byte) (*Response, error) {
return nil, nil
}
func (h *noopClientHandler) ResponseData(context.Context, chan []byte, *Response) error {
func (h *noopClientHandler) ResponseData(context.Context, <-chan []byte, *Response) error {
return nil
}
@ -932,7 +931,7 @@ func (h *noopClientHandler) HandleResponse(context.Context, *Response) error {
type testClientHandler struct{ logger *logrus.Logger }
func (h *testClientHandler) Send(ctx context.Context, command *Command, out chan []byte) error {
func (h *testClientHandler) Send(ctx context.Context, command *Command, out chan<- []byte) error {
h.logger.Infof("send command %s", command.Announce.Code)
select {
@ -957,7 +956,7 @@ func (h *testClientHandler) Send(ctx context.Context, command *Command, out chan
return nil
}
func (h *testClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte) (*Response, error) {
func (h *testClientHandler) ResponseAnnounce(ctx context.Context, in <-chan []byte) (*Response, error) {
select {
case <-ctx.Done():
return nil, nil
@ -970,7 +969,7 @@ func (h *testClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte
}
}
func (h *testClientHandler) ResponseData(ctx context.Context, in chan []byte, response *Response) error {
func (h *testClientHandler) ResponseData(ctx context.Context, in <-chan []byte, response *Response) error {
select {
case <-ctx.Done():
return nil
@ -991,7 +990,7 @@ func (h *testClientHandler) HandleResponse(_ context.Context, response *Response
type commandAnnounceErrClientHandler struct{ testClientHandler }
func (h *commandAnnounceErrClientHandler) Send(context.Context, *Command, chan []byte) error {
func (h *commandAnnounceErrClientHandler) Send(context.Context, *Command, chan<- []byte) error {
return errors.New("failed sending command")
}
@ -1011,7 +1010,7 @@ func TestNewClient(t *testing.T) {
type responseAnnounceErrClientHandler struct{ testClientHandler }
func (h *responseAnnounceErrClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte) (*Response, error) {
func (h *responseAnnounceErrClientHandler) ResponseAnnounce(ctx context.Context, in <-chan []byte) (*Response, error) {
select {
case <-ctx.Done():
return nil, nil
@ -1022,7 +1021,7 @@ func (h *responseAnnounceErrClientHandler) ResponseAnnounce(ctx context.Context,
type responseAnnounceNilClientHandler struct{ testClientHandler }
func (h *responseAnnounceNilClientHandler) ResponseAnnounce(ctx context.Context, in chan []byte) (*Response, error) {
func (h *responseAnnounceNilClientHandler) ResponseAnnounce(ctx context.Context, in <-chan []byte) (*Response, error) {
select {
case <-ctx.Done():
return nil, nil
@ -1033,7 +1032,7 @@ func (h *responseAnnounceNilClientHandler) ResponseAnnounce(ctx context.Context,
type responseDataErrClientHandler struct{ testClientHandler }
func (h *responseDataErrClientHandler) ResponseData(ctx context.Context, in chan []byte, _ *Response) error {
func (h *responseDataErrClientHandler) ResponseData(ctx context.Context, in <-chan []byte, _ *Response) error {
select {
case <-ctx.Done():
return nil
@ -1044,7 +1043,7 @@ func (h *responseDataErrClientHandler) ResponseData(ctx context.Context, in chan
type responseDataTimeoutErrClientHandler struct{ testClientHandler }
func (h *responseDataTimeoutErrClientHandler) ResponseData(ctx context.Context, in chan []byte, _ *Response) error {
func (h *responseDataTimeoutErrClientHandler) ResponseData(ctx context.Context, in <-chan []byte, _ *Response) error {
select {
case <-ctx.Done():
return nil
@ -1055,7 +1054,7 @@ func (h *responseDataTimeoutErrClientHandler) ResponseData(ctx context.Context,
type responseDataNilClientHandler struct{ testClientHandler }
func (h *responseDataNilClientHandler) ResponseData(ctx context.Context, in chan []byte, response *Response) error {
func (h *responseDataNilClientHandler) ResponseData(ctx context.Context, in <-chan []byte, response *Response) error {
select {
case <-ctx.Done():
return nil
@ -1194,6 +1193,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", handleResponse)},
@ -1377,6 +1377,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.ErrorLevel, "could not handle response announce"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
@ -1441,6 +1442,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
})
@ -1505,6 +1507,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
{logrus.ErrorLevel, "could not handle response data"},
@ -1571,6 +1574,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
{logrus.ErrorLevel, "could not handle response data"},
@ -1637,6 +1641,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", handleResponse)},
@ -1703,6 +1708,7 @@ func TestClientProtocol_Handle(t *testing.T) { //nolint:cyclop
assertLogs(t, pHook, []expectedLogs{
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", cmdAnnounce)},
{logrus.TraceLevel, "handled command"},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respAnnounce)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", respData)},
{logrus.DebugLevel, fmt.Sprintf("handling protocol state %s", handleResponse)},