diff --git a/changelog.md b/changelog.md index 134d28ff..feb14c96 100644 --- a/changelog.md +++ b/changelog.md @@ -1,12 +1,24 @@ v0.28.0 ======= -Centrifuge v0.28.0 comes with an updated Redis Engine implementation based on [rueian/rueidis](https://github.com/rueian/rueidis) library. Allocation efficiency and throughput of Redis `Broker` and `PresenceManager` were improved in both standalone and Cluster Redis setups. See [#262](https://github.com/centrifugal/centrifuge/pull/262) and [pr with blog post we are preparing](https://github.com/centrifugal/centrifugal.dev/pull/18) for the reasoning and numbers behind. +* Centrifuge v0.28.0 comes with an updated Redis Engine implementation based on [rueian/rueidis](https://github.com/rueian/rueidis) library. Allocation efficiency and throughput of Redis `Broker` and `PresenceManager` were improved in both standalone and Cluster Redis setups. See [#262](https://github.com/centrifugal/centrifuge/pull/262) and blog post [Improving Centrifugo Redis Engine throughput and allocation efficiency with Rueidis Go library](https://centrifugal.dev/blog/2022/12/20/improving-redis-engine-performance) for the reasoning and numbers behind. +* Work on a better observability and possibility to protect client protocol from misusing: Centrifuge now has `CommandReadHandler` and `CommandProcessedHandler`. These handlers are only available for client protocol v2, client protocol v1 [will be removed soon](https://github.com/centrifugal/centrifuge/issues/275). +* Client now can't send infinite number of pongs to the server, only one pong after receiving ping is allowed +* Client now can't send any command to the server after getting error in Connect command +* Disconnect client if it sends async message (using `Send` method) to the server while `MessageHandler` not set +* Possibility to dramatically reduce server CPU usage (it may be up to 5x reduction depending on message rate) in case of sending many messages towards individual connections. This is possible with new options of `ConnectReply`: `WriteDelay`, `ReplyWithoutQueue`, `MaxMessagesInFrame` which allow tweaking Centrifuge message write loop. See [#270](https://github.com/centrifugal/centrifuge/pull/270) for more details. +* Several internal optimizations in client protocol to reduce memory allocations a bit. +* More human-readable tracing logging output (especially in Protobuf protocol case). On the other hand, tracing log level is much more expensive now. We never assumed it will be used in production – so seems an acceptable trade-off. +* Update centrifuge-js version in all examples ``` -gorelease -base v0.27.0 -version v0.28.0 +gorelease -base v0.27.2 -version v0.28.0 + # github.com/centrifugal/centrifuge ## incompatible changes +(*Client).Handle: removed +(*Client).HandleCommand: changed from func(*github.com/centrifugal/protocol.Command) bool to func(*github.com/centrifugal/protocol.Command, int) bool +CommandReadHandler: changed from func(*Client, CommandReadEvent) to func(*Client, CommandReadEvent) error DefaultRedisBrokerPrefix: removed DefaultRedisConnectTimeout: removed DefaultRedisPresenceManagerPrefix: removed @@ -20,6 +32,21 @@ RedisShardConfig.TLSSkipVerify: removed RedisShardConfig.UseTLS: removed RedisShardConfig.WriteTimeout: removed ## compatible changes +(*Node).OnCommandProcessed: added +CommandProcessedEvent: added +CommandProcessedHandler: added +CommandReadEvent.CommandSize: added +Config.EnabledProtocolVersions: added +Config.ProtocolVersionEnabled: added +ConnectReply.MaxMessagesInFrame: added +ConnectReply.QueueInitialCap: added +ConnectReply.ReplyWithoutQueue: added +ConnectReply.WriteDelay: added +DisconnectNotAvailable: added +DisconnectPermissionDenied: added +DisconnectTooManyErrors: added +DisconnectTooManyRequests: added +HandleReadFrame: added RedisShardConfig.ClientName: added RedisShardConfig.IOTimeout: added RedisShardConfig.SentinelClientName: added diff --git a/config.go b/config.go index 373fa0a6..d9b5f140 100644 --- a/config.go +++ b/config.go @@ -78,23 +78,6 @@ type Config struct { // UseSingleFlight allows turning on mode where singleflight will be automatically used // for Node.History (including recovery) and Node.Presence/Node.PresenceStats calls. UseSingleFlight bool - // EnabledProtocolVersions allows limiting versions of Protocol server may serve. - // By default, both ProtocolVersion1 and ProtocolVersion2 may be served at the moment. - // Note that ProtocolVersion1 is deprecated and will be completely removed soon. - EnabledProtocolVersions []ProtocolVersion -} - -func (c Config) ProtocolVersionEnabled(protoVersion ProtocolVersion) bool { - if len(c.EnabledProtocolVersions) == 0 { - // All by default. - return true - } - for _, v := range c.EnabledProtocolVersions { - if protoVersion == v { - return true - } - } - return false } const ( diff --git a/handler_http_stream.go b/handler_http_stream.go index 58159213..be1365aa 100644 --- a/handler_http_stream.go +++ b/handler_http_stream.go @@ -80,12 +80,6 @@ func (h *HTTPStreamHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { pongTimeout: pongTimeout, }) - if !h.node.config.ProtocolVersionEnabled(transport.ProtocolVersion()) { - h.node.logger.log(newLogEntry(LogLevelInfo, "unsupported protocol version", map[string]interface{}{"transport": transportHTTPStream, "version": transport.ProtocolVersion()})) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - c, closeFn, err := NewClient(r.Context(), h.node, transport) if err != nil { h.node.Log(NewLogEntry(LogLevelError, "error create client", map[string]interface{}{"error": err.Error(), "transport": transportHTTPStream})) diff --git a/handler_sockjs.go b/handler_sockjs.go index ad326a32..8161fc63 100644 --- a/handler_sockjs.go +++ b/handler_sockjs.go @@ -155,8 +155,7 @@ func (s *SockjsHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { } } - if !s.node.config.ProtocolVersionEnabled(protoVersion) { - s.node.logger.log(newLogEntry(LogLevelInfo, "unsupported protocol version", map[string]interface{}{"transport": transportSockJS, "version": protoVersion})) + if DisableProtocolVersion1 && protoVersion == ProtocolVersion1 { http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } diff --git a/handler_sse.go b/handler_sse.go index 29b38229..7e4e36bd 100644 --- a/handler_sse.go +++ b/handler_sse.go @@ -78,12 +78,6 @@ func (h *SSEHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { transport := newSSETransport(r, sseTransportConfig{pingInterval: pingInterval, pongTimeout: pongTimeout}) - if !h.node.config.ProtocolVersionEnabled(transport.ProtocolVersion()) { - h.node.logger.log(newLogEntry(LogLevelInfo, "unsupported protocol version", map[string]interface{}{"transport": transportSSE, "version": transport.ProtocolVersion()})) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - c, closeFn, err := NewClient(r.Context(), h.node, transport) if err != nil { h.node.Log(NewLogEntry(LogLevelError, "error create client", map[string]interface{}{"error": err.Error(), "transport": "uni_sse"})) diff --git a/handler_websocket.go b/handler_websocket.go index f796bc6a..da83a2d9 100644 --- a/handler_websocket.go +++ b/handler_websocket.go @@ -138,8 +138,7 @@ func (s *WebsocketHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { } } - if !s.node.config.ProtocolVersionEnabled(protoVersion) { - s.node.logger.log(newLogEntry(LogLevelInfo, "unsupported protocol version", map[string]interface{}{"transport": transportWebsocket, "version": protoVersion})) + if DisableProtocolVersion1 && protoVersion == ProtocolVersion1 { http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } diff --git a/transport.go b/transport.go index 2750bf22..c673c8e9 100644 --- a/transport.go +++ b/transport.go @@ -33,6 +33,11 @@ const ( PushFlagMessage ) +// DisableProtocolVersion1 is a temporary global flag which may be set to +// disabling usage of ProtocolVersion1. This flag will be removed soon together +// with ProtocolVersion1. +var DisableProtocolVersion1 bool + // ProtocolVersion defines protocol behavior. type ProtocolVersion uint8