From 4835fdf237255db648ec776b0503ce222f291535 Mon Sep 17 00:00:00 2001 From: Keagan McClelland Date: Mon, 29 Jul 2024 15:14:58 -0700 Subject: [PATCH] fn: Add new Req type to abstract the pattern of remote processing. It is common throughout the codebase to send data to a remote goroutine for processing. Typically, along with the data we are processing, we also send a one-shot channel where we intend to listen for the response. This type encapsulates that pattern. --- fn/req.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 fn/req.go diff --git a/fn/req.go b/fn/req.go new file mode 100644 index 000000000..0b200b44e --- /dev/null +++ b/fn/req.go @@ -0,0 +1,34 @@ +package fn + +// Req is a type to encapsulate RPC-like calls wherein we send some data +// structure as a request, as well as a channel to receive the response on where +// the remote goroutine will send the result. +// +// NOTE: This construct should only be used for request/response patterns for +// which there is only a single response for the request. +type Req[Input any, Output any] struct { + // Request is the data we are sending to the remote goroutine for + // processing. + Request Input + + // Response is the channel on which we will receive the result of the + // remote computation. + Response chan<- Output +} + +// NewReq is the base constructor of the Req type. It returns both the packaged +// Req object as well as the receive side of the response channel that we will +// listen on for the response. +func NewReq[Input, Output any](input Input) ( + Req[Input, Output], <-chan Output) { + + // Always buffer the response channel so that the goroutine doing the + // processing job does not block if the original requesting routine + // takes an unreasonably long time to read the response. + responseChan := make(chan Output, 1) + + return Req[Input, Output]{ + Request: input, + Response: responseChan, + }, responseChan +}