diff --git a/config.go b/config.go index c91e3d24..595a2e73 100644 --- a/config.go +++ b/config.go @@ -6,11 +6,11 @@ import ( // Config contains Node configuration options. type Config struct { - // Version of server – will be sent to client on connection establishment + // Version of server – will be sent to a client on connection establishment // phase in response to connect request. Version string - // Name of this server Node - must be unique, used as human readable and - // meaningful node identifier. If not set then os.Hostname will be used. + // Name is a unique name of current server Node. Name used as human readable + // and meaningful node identifier. If not set then os.Hostname will be used. Name string // LogLevel is a log level to use. By default nothing will be logged. LogLevel LogLevel @@ -71,7 +71,6 @@ const ( // DefaultConfig is Config initialized with default values for all fields. var DefaultConfig = Config{ - ChannelMaxLength: 255, NodeInfoMetricsAggregateInterval: 60 * time.Second, ClientPresenceUpdateInterval: 25 * time.Second, ClientPresenceExpireInterval: 60 * time.Second, @@ -79,6 +78,7 @@ var DefaultConfig = Config{ ClientExpiredSubCloseDelay: 25 * time.Second, ClientStaleCloseDelay: 25 * time.Second, ClientChannelPositionCheckDelay: 40 * time.Second, - ClientQueueMaxSize: 10485760, // 10MB by default + ClientQueueMaxSize: 10485760, // 10MB by default. ClientChannelLimit: 128, + ChannelMaxLength: 255, } diff --git a/credentials.go b/credentials.go index b65266c6..82318095 100644 --- a/credentials.go +++ b/credentials.go @@ -4,24 +4,26 @@ import "context" // Credentials allows to authenticate connection when set into context. type Credentials struct { - // UserID tells library an ID of connecting user. + // UserID tells library an ID of current user. Leave this empty string + // if you need access from anonymous user. UserID string // ExpireAt allows to set time in future when connection must be validated. - // In this case OnRefresh callback must be set by application. + // In this case Client.OnRefresh callback must be set by application. Zero + // value means no expiration. ExpireAt int64 - // Info contains additional information about connection. This will be + // Info contains additional information about connection. This data will be // included untouched into Join/Leave messages, into Presence information, - // also info becomes a part of published message if it was published from - // client directly. In some cases having additional info can be an - // overhead – but you are simply free to not use it. + // also info can become a part of published message as part of ClientInfo. + // In some cases having additional info can be an undesired overhead – but + // you are simply free to not use this field at all. Info []byte } -// credentialsContextKeyType is special type to safely use -// context for setting and getting Credentials. +// credentialsContextKeyType is special type to safely use context for setting +// and getting Credentials. type credentialsContextKeyType int -// CredentialsContextKey allows Go code to set Credentials into context. +// credentialsContextKey allows Go code to set Credentials into context. var credentialsContextKey credentialsContextKeyType // SetCredentials allows to set connection Credentials to Context. Credentials set @@ -32,7 +34,7 @@ func SetCredentials(ctx context.Context, cred *Credentials) context.Context { return ctx } -// GetCredentials allows to get previously set Credentials from Context. +// GetCredentials allows to extract Credentials from Context (if set previously). func GetCredentials(ctx context.Context) (*Credentials, bool) { if val := ctx.Value(credentialsContextKey); val != nil { cred, ok := val.(*Credentials) diff --git a/doc.go b/doc.go index 849dae8f..9118209c 100644 --- a/doc.go +++ b/doc.go @@ -1,15 +1,18 @@ // Package centrifuge is a real-time messaging library that abstracts // several bidirectional transports (Websocket, SockJS) and provides -// primitives to build real-time applications with Go. It's also used as -// core of Centrifugo server (https://github.com/centrifugal/centrifugo). -// -// The API of this library is almost all goroutine-safe except cases where -// one-time operations like setting callback handlers performed. Library -// expects that code inside callbacks will not block. +// primitives to build scalable real-time applications with Go. It's +// also used as a core of Centrifugo server (https://github.com/centrifugal/centrifugo). // // Centrifuge library provides several features on top of plain Websocket // implementation - read highlights in library README on Github – // https://github.com/centrifugal/centrifuge. // +// The API of this library is almost all goroutine-safe except cases where +// one-time operations like setting callback handlers performed, also your +// code inside event handlers should be synchronized since event handlers +// can be called concurrently. Library expects that code inside event handlers +// will not block. See more information about client connection lifetime and +// event handler order/concurrency in README on Github. +// // Also check out examples in repo to see main library concepts in action. package centrifuge diff --git a/engine.go b/engine.go index 5f9a7f35..fe1a13c5 100644 --- a/engine.go +++ b/engine.go @@ -76,9 +76,8 @@ type StreamPosition struct { Epoch string } -// Closer is an interface that Broker, HistoryManager and PresenceManager can -// optionally implement if they need to close any resources on Centrifuge node -// shutdown. +// Closer is an interface that Broker and PresenceManager can optionally implement +// if they need to close any resources on Centrifuge Node graceful shutdown. type Closer interface { // Close when called should clean up used resources. Close(ctx context.Context) error diff --git a/engine_memory.go b/engine_memory.go index 0d9806e6..fcd59192 100644 --- a/engine_memory.go +++ b/engine_memory.go @@ -38,12 +38,14 @@ var _ Engine = (*MemoryEngine)(nil) // MemoryEngineConfig is a memory engine config. type MemoryEngineConfig struct { // HistoryMetaTTL sets a time of inactive stream meta information expiration. + // This information contains an epoch and offset of each stream. Having this + // meta information helps in message recovery process. // Must have a reasonable value for application. // At moment works with seconds precision. - // TODO v1: maybe make this channel namespace option? - // TODO v1: since we have epoch things should also properly work without meta + // TODO v1: since we have epoch, things should also properly work without meta // information at all (but we loose possibility of long-term recover in stream - // without new messages). + // without new messages). We can make this optional and disabled by default at + // least. HistoryMetaTTL time.Duration } diff --git a/engine_redis.go b/engine_redis.go index 327e689c..9f6ecaa7 100644 --- a/engine_redis.go +++ b/engine_redis.go @@ -62,9 +62,9 @@ const ( // RedisEngine uses Redis to implement Engine functionality. // This engine allows to scale Centrifuge based server to many instances and // load balance client connections between them. -// Redis engine supports additionally supports Sentinel, client-side sharding -// and can work with Redis Cluster (or client-side shard between different -// Redis Clusters). +// Redis engine additionally supports Redis Sentinel, client-side consistent +// sharding and can work with Redis Cluster (including client-side sharding +// between different Redis Clusters to scale PUB/SUB). type RedisEngine struct { node *Node sharding bool @@ -113,10 +113,10 @@ type RedisEngineConfig struct { // value to this option (usually much bigger than history retention period) // can help. In this case unused channel stream meta data will eventually expire. // - // TODO v1: maybe make this channel namespace option? - // TODO v1: since we have epoch things should also properly work without meta + // TODO v1: since we have epoch, things should also properly work without meta // information at all (but we loose possibility of long-term recover in stream - // without new messages). + // without new messages). We can make this optional and disabled by default at + // least. HistoryMetaTTL time.Duration // UseStreams allows to enable usage of Redis streams instead of list data diff --git a/metrics.go b/metrics.go index 2bd44528..98b56217 100644 --- a/metrics.go +++ b/metrics.go @@ -50,7 +50,7 @@ var ( actionCountRemovePresence prometheus.Counter actionCountPresence prometheus.Counter actionCountPresenceStats prometheus.Counter - actionCountHistoryFull prometheus.Counter + actionCountHistory prometheus.Counter actionCountHistoryRecover prometheus.Counter actionCountHistoryStreamTop prometheus.Counter actionCountHistoryRemove prometheus.Counter @@ -275,8 +275,8 @@ func incActionCount(action string) { actionCountPresence.Inc() case "presence_stats": actionCountPresenceStats.Inc() - case "history_full": - actionCountHistoryFull.Inc() + case "history": + actionCountHistory.Inc() case "history_recover": actionCountHistoryRecover.Inc() case "history_stream_top": @@ -414,7 +414,7 @@ func initMetricsRegistry(registry prometheus.Registerer, metricsNamespace string actionCountRemovePresence = actionCount.WithLabelValues("remove_presence") actionCountPresence = actionCount.WithLabelValues("presence") actionCountPresenceStats = actionCount.WithLabelValues("presence_stats") - actionCountHistoryFull = actionCount.WithLabelValues("history_full") + actionCountHistory = actionCount.WithLabelValues("history") actionCountHistoryRecover = actionCount.WithLabelValues("history_recover") actionCountHistoryStreamTop = actionCount.WithLabelValues("history_stream_top") actionCountHistoryRemove = actionCount.WithLabelValues("history_remove") diff --git a/node.go b/node.go index 43220168..8e121f72 100644 --- a/node.go +++ b/node.go @@ -318,9 +318,13 @@ func (n *Node) cleanNodeInfo() { } } -// Channels returns list of all channels currently active across on all nodes. -// This is a snapshot of state mostly useful for understanding what's going on -// with system. +// Channels returns a slice of all channels currently active across all +// Centrifuge nodes. +// This is an instant snapshot of state, mostly useful for debugging in +// development. +// It does not scale well for massive deployments with large number of active +// channels since response can be large. +// Deprecated. See https://github.com/centrifugal/centrifuge/issues/147. func (n *Node) Channels() ([]string, error) { return n.broker.Channels() } @@ -837,6 +841,7 @@ type HistoryResult struct { // History allows to extract Publications in channel. // The channel must belong to namespace where history is on. func (n *Node) History(ch string, opts ...HistoryOption) (HistoryResult, error) { + incActionCount("history") historyOpts := &HistoryOptions{} for _, opt := range opts { opt(historyOpts)