mirror of
https://github.com/redis/go-redis.git
synced 2025-07-28 06:42:00 +03:00
feat: implement strongly typed HandlerContext with concrete types in main package
Move push notification handler and context interfaces to main package to enable strongly typed getters using concrete Redis client types instead of interfaces. This provides much better type safety and usability for push notification handlers. Key Changes: 1. Main Package Implementation: - Moved PushNotificationHandlerContext to push_notifications.go - Moved PushNotificationHandler to push_notifications.go - Implemented concrete types for all getters - GetClusterClient() returns *ClusterClient - GetSentinelClient() returns *SentinelClient - GetRegularClient() returns *Client - GetPubSub() returns *PubSub 2. Concrete Type Benefits: - No need for interface definitions or type assertions - Direct access to concrete client methods and properties - Compile-time type checking with actual client types - IntelliSense support for all client-specific methods - No runtime panics from incorrect type casting 3. Handler Interface with Concrete Types: ```go type PushNotificationHandlerContext interface { GetClusterClient() *ClusterClient GetSentinelClient() *SentinelClient GetRegularClient() *Client GetPubSub() *PubSub GetConn() *pool.Conn IsBlocking() bool } ``` 4. Adapter Pattern Implementation: - Created handlerAdapter to bridge internal and public interfaces - Created voidProcessorAdapter for void processor functionality - Seamless conversion between internal and public contexts - Maintains compatibility with existing internal architecture 5. Context Conversion Functions: - convertInternalToPublicContext() for seamless conversion - Proper context bridging between internal and public APIs - Maintains all context information during conversion - Consistent behavior across all client types 6. Updated All Integration Points: - Updated redis.go to use public context conversion - Updated pubsub.go to use public context conversion - Updated sentinel.go to use void processor adapter - Maintained backward compatibility with existing code 7. Handler Usage Example: ```go func (h *MyHandler) HandlePushNotification( ctx context.Context, handlerCtx PushNotificationHandlerContext, notification []interface{}, ) bool { // Direct access to concrete types - no casting needed! if clusterClient := handlerCtx.GetClusterClient(); clusterClient != nil { // Full access to ClusterClient methods nodes := clusterClient.ClusterNodes(ctx) // ... cluster-specific logic } if regularClient := handlerCtx.GetRegularClient(); regularClient != nil { // Full access to Client methods info := regularClient.Info(ctx) // ... regular client logic } return true } ``` 8. Type Safety Improvements: - No interface{} fields in public API - Concrete return types for all getters - Compile-time verification of client type usage - Clear API with explicit client type access - Enhanced developer experience with full type information Benefits: - Strongly typed access to concrete Redis client types - No type assertions or interface casting required - Full IntelliSense support for client-specific methods - Compile-time type checking prevents runtime errors - Clean public API with concrete types - Seamless integration with existing internal architecture - Enhanced developer experience and productivity This implementation provides handlers with direct access to concrete Redis client types while maintaining the flexibility and context information needed for sophisticated push notification handling, particularly important for hitless upgrades and cluster management operations.
This commit is contained in:
10
redis.go
10
redis.go
@ -1122,7 +1122,9 @@ func (c *baseClient) processPushNotifications(ctx context.Context, cn *pool.Conn
|
||||
return cn.WithReader(ctx, 0, func(rd *proto.Reader) error {
|
||||
// Create handler context with client, connection pool, and connection information
|
||||
handlerCtx := c.pushNotificationHandlerContext(cn)
|
||||
return c.pushProcessor.ProcessPendingNotifications(ctx, handlerCtx, rd)
|
||||
// Convert internal context to public context for the processor
|
||||
publicCtx := convertInternalToPublicContext(handlerCtx)
|
||||
return c.pushProcessor.ProcessPendingNotifications(ctx, publicCtx, rd)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1135,10 +1137,14 @@ func (c *baseClient) processPendingPushNotificationWithReader(ctx context.Contex
|
||||
|
||||
// Create handler context with client, connection pool, and connection information
|
||||
handlerCtx := c.pushNotificationHandlerContext(cn)
|
||||
return c.pushProcessor.ProcessPendingNotifications(ctx, handlerCtx, rd)
|
||||
// Convert internal context to public context for the processor
|
||||
publicCtx := convertInternalToPublicContext(handlerCtx)
|
||||
return c.pushProcessor.ProcessPendingNotifications(ctx, publicCtx, rd)
|
||||
}
|
||||
|
||||
// pushNotificationHandlerContext creates a handler context for push notification processing
|
||||
func (c *baseClient) pushNotificationHandlerContext(cn *pool.Conn) pushnotif.HandlerContext {
|
||||
return pushnotif.NewHandlerContext(c, c.connPool, nil, cn, false)
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user