You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently users must manually handle push responses from Redis which is not only tedious, but also impractical since push responses can come before any other response so handling them correctly requires checking for push responses on any command!
A case where this may happen is with client tracking. In this case the server can send out push messages at any point since the push can be caused by any connection. Even if an application uses the [REDIRECT client-id] option to redirect the push messages to another client, a push message may still be received when the other client is closed.
To better support handling of push messages, both in general and for use with server-assisted client side caching, we should think about a way to let users handle push messages automatically.
From my perspective there are 2 obvious places where such logic could live:
In the Conn implementation(s).
In the Unmarshalers / the Unmarshal function
There may be other options, but none come to my mind.
Option 1 would probably be the simplest solution. We could add an optional handler function that receives the push responses (or just a reader) and can do with them whatever it wants, with a default / nil handler that discards pushes.
Option 2 would be more complex and every Unmarshaler would need to manually handle push messages and we would need to somehow pass the handler to UnmarshalRESP (e.g. as a new field on resp.Opts).
Given these 2 options I think option 1 would be the best.
This would probably need some extra logic to allow our pubsub logic to continue working since pubSubConn would not be able to receive pushes anymore. It may be possible to handle this as a special case in our Conn implementation, but it may be better to add "first-level" support for handling pushes on the command level. The idea here is to add a new interface in the resp package that would allow unmarshaling pushes instead of leaving this to the Conn.
A bit off topic: Looking at the PushUnmarshaler interface I can't help but think that something like this may be useful for dealing with attributes as well.
The text was updated successfully, but these errors were encountered:
Having thought about this a bit more, I think a PushUnmarshaler interface that can be implemented by any Unmarshaer isn't really as clean as I initially thought. While it should work, having any Unmarshaler possibly also handle pushes, which have nothing do to with the normal response, just seems like the wrong solution. (Though something like an AttributeHandler interface for unmarshalers that can unmarshal their own attributes still sounds like an interesting idea to me, but that's for another issue)
Maybe we could just have a concrete implementation (e.g .a PushReceiver) that unmarshals pushes into a Rcv interface{} field which we then could handle as a special case. Basically if a Conn needs to unmarshal a response and the receiver is of this concrete type we would skip the normal PushHandler.
So instead of this
ifpu, ok:=mu.unmarshalInto.(resp.PushUnmarshaler); ok {
err:=pu.UnmashalRESPPush(br, o)
iferr!=nil {
// ...
}
} else {
handler:=c.pushHandler// our callbackifhandler==nil {
handler=discardHandler// handler that just discards the message
}
err:=handler(c.br, c.rOpts)
iferr!=nil {
// ...
}
}
we could have something like this
if_, isPushUnmarshaler=mu.unmarshalInto.(PushUnmarshaler); !isPushUnmarshaler {
handler:=c.pushHandler// our callbackifhandler==nil {
handler=discardHandler// handler that just discards the message
}
err:=handler(c.br, c.rOpts)
iferr!=nil {
// ...
}
}
Currently users must manually handle push responses from Redis which is not only tedious, but also impractical since push responses can come before any other response so handling them correctly requires checking for push responses on any command!
A case where this may happen is with client tracking. In this case the server can send out push messages at any point since the push can be caused by any connection. Even if an application uses the
[REDIRECT client-id]
option to redirect the push messages to another client, a push message may still be received when the other client is closed.To better support handling of push messages, both in general and for use with server-assisted client side caching, we should think about a way to let users handle push messages automatically.
From my perspective there are 2 obvious places where such logic could live:
Conn
implementation(s).Unmarshaler
s / theUnmarshal
functionThere may be other options, but none come to my mind.
Option 1 would probably be the simplest solution. We could add an optional handler function that receives the push responses (or just a reader) and can do with them whatever it wants, with a default / nil handler that discards pushes.
Option 2 would be more complex and every
Unmarshaler
would need to manually handle push messages and we would need to somehow pass the handler toUnmarshalRESP
(e.g. as a new field onresp.Opts
).Given these 2 options I think option 1 would be the best.
This would probably need some extra logic to allow our pubsub logic to continue working since
pubSubConn
would not be able to receive pushes anymore. It may be possible to handle this as a special case in ourConn
implementation, but it may be better to add "first-level" support for handling pushes on the command level. The idea here is to add a new interface in theresp
package that would allow unmarshaling pushes instead of leaving this to theConn
.Something like this
Using the default
Conn
implementation (conn
) as an example, we could then do something like thisA bit off topic: Looking at the
PushUnmarshaler
interface I can't help but think that something like this may be useful for dealing with attributes as well.The text was updated successfully, but these errors were encountered: