mirror of
https://github.com/zrepl/zrepl.git
synced 2025-08-17 18:31:02 +02:00
rpc: re-architect connection teardown
Tear down occurs on each protocol level, stack-wise. Open RWC Open ML (with NewMessageLayer) Open RPC (with NewServer/ NewClient) Close RPC (with Close() from Client()) Close ML * in Server: after error / receive of Close request * in Client: after getting ACK for Close request from Server Close RWC To achieve this, a DataType for RPC control messages was added, which has a separate set of endpoints. Not exactly pretty, but works for now. The necessity of the RST frame remains to be determined. However, it is nice to have a way to signal the other side something went terribly wrong in the middle of an operation. Example: A frameBridingWriter fails to read the next chunk of a file it is supposed to send, it can just send an RST frame to signal this operation failed... Wouldn't trailers make sense then?
This commit is contained in:
@ -28,10 +28,35 @@ func (c *Client) SetLogger(logger Logger, logMessageLayer bool) {
|
||||
}
|
||||
|
||||
func (c *Client) Close() (err error) {
|
||||
err = c.ml.HangUp()
|
||||
if err == RST {
|
||||
return nil
|
||||
|
||||
c.logger.Printf("sending Close request")
|
||||
header := Header{
|
||||
DataType: DataTypeControl,
|
||||
Endpoint: ControlEndpointClose,
|
||||
Accept: DataTypeControl,
|
||||
}
|
||||
err = c.ml.WriteHeader(&header)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.logger.Printf("reading Close ACK")
|
||||
ack, err := c.ml.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.logger.Printf("received Close ACK: %#v", ack)
|
||||
if ack.Error != StatusOK {
|
||||
err = errors.Errorf("error hanging up: remote error (%s) %s", ack.Error, ack.ErrorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
c.logger.Printf("closing MessageLayer")
|
||||
if err = c.ml.Close(); err != nil {
|
||||
c.logger.Printf("error closing RWC: %+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user