Server push
Server push
What “server push” refers to is: server sends a message to client after occurrence of an event, rather than passively replying the client as in ordinary RPCs. Following two methods are recommended to implement server push in brpc.
Similar to local event, remote event is divided into two steps: registration and notification. The client sends an asynchronous RPC to the server for registration, and puts the event-handling code in the RPC callback. The RPC is also a part of the waiting for the notification, namely the server does not respond directly after receiving the request, instead it does not call done->Run() (to notify the client) until the local event triggers. As we see, the server is also asynchronous. If the connection is broken during the process, the client fails soon and may choose to retry another server or end the RPC. Server should be aware of the disconnection by using Controller.NotifyOnCancel() and delete useless done in-time.
- Client also needs to know how to deal with the message. If the client does not have the handling code, the message is still useless.
In other words, the client should “be prepared” to the messages from the server, and the “preparation” often relies on programming contexts that client just faces. Regarding different factors, it’s more universal for client to inform server for “I am ready” (registered) first, then the server notifies the client with events later, in which case the “push” is just a “response”, with a very long or even infinite timeout.
In some scenarios, the registration can be ignored, such as the push promise in http2, which does not require the web browser(client) to register with the server, because both client and server know that the task between them is to let the client download necessary resources ASAP. Since each resource has a unique URI, the server can directly push resources and URI to the client, which caches the resources to avoid repeated accesses. Similarly, protocols capable of “two-way communication” probably improves efficiencies of pushing in given scenarios such as multimedia streaming or fixed-format key/value pairs etc, rather than implementing universal pushing. The client knows how to handle messages that may be pushed by servers, so extra registrations are not required. The push can still be treated as a “response”: to the request that client already and always promised server.
Restful callback
URL and parameters must contain enough information to make the callback know that which notification corresponds to which request, because the client may care about more than one event at the same time, or an event may be registered more than once due to network jitter or restarting machines etc. If the URL path is fixed, the client should place an unique ID in the registration request and the server should put the ID unchanged in response. Or the client generates an unique path for each registration so that each request is distinguishable from each other naturally. These methods are actually same in essense, just different positions for unique identifiers.
Callbacks should deal with idempotence. The server may retry and send more than one notifications after encountering network problems. If the first notification has been successful, follow-up notifications should not have effects. The “remote event” pattern guarantees idempotency at the layer of RPC, which ensures that the done is called once and only once.