@@ -202,10 +202,12 @@ func (cfg *AutoPipelineConfig) Validate() error {
202202}
203203
204204// cmdableClient is an interface for clients that support pipelining.
205- // Both Client and ClusterClient implement this interface.
205+ // Both Client and ClusterClient implement this interface. It embeds
206+ // UniversalClient (Cmdable + Process + Do + AddHook + Watch + Subscribe... +
207+ // Close + PoolStats) so the AutoPipeliner can delegate the non-batched surface
208+ // back to the underlying client and itself satisfy UniversalClient.
206209type cmdableClient interface {
207- Cmdable
208- Process (ctx context.Context , cmd Cmder ) error
210+ UniversalClient
209211 // processPipelineHook is the hook-wrapped []Cmder pipeline entry — the same
210212 // method Pipeline.Exec is wired to (see Client.Pipeline). The flusher
211213 // dispatches drained batches through it directly, skipping the per-batch
@@ -586,7 +588,7 @@ func newAutoPipeliner(pipeliner cmdableClient, config *AutoPipelineConfig, block
586588// a blocking autopipeliner the call blocks until the command has executed; on a
587589// deferred (async) one it returns immediately and the command's result
588590// accessors (Err/Val/Result) block until it completes.
589- func (ap * AutoPipeliner ) Do (ctx context.Context , args ... interface {}) Cmder {
591+ func (ap * AutoPipeliner ) Do (ctx context.Context , args ... interface {}) * Cmd {
590592 cmd := NewCmd (ctx , args ... )
591593 if len (args ) == 0 {
592594 cmd .SetErr (errDoNoArgs )
@@ -624,6 +626,61 @@ func (ap *AutoPipeliner) Process(ctx context.Context, cmd Cmder) error {
624626 return ap .cmdable (ctx , cmd )
625627}
626628
629+ // The methods below complete the UniversalClient surface by delegating to the
630+ // underlying client. They are NOT autopipelined — pub/sub, transactions (Watch),
631+ // hooks, Do and pool stats cannot be batched — so an AutoPipeliner used as a
632+ // UniversalClient batches only the typed data commands; everything here runs on
633+ // the underlying client exactly as it would there.
634+ //
635+ // Note on lifecycle: Close() (defined elsewhere) closes the AUTOPIPELINER —
636+ // drains in-flight batches and stops flushers — but does NOT close the
637+ // underlying client, whose lifecycle is owned by whoever created it.
638+
639+ // AddHook adds a hook to the underlying client. Autopipelined batches are hooked
640+ // too, since dispatch goes through the hook-wrapped pipeline entry.
641+ func (ap * AutoPipeliner ) AddHook (hook Hook ) { ap .pipeliner .AddHook (hook ) }
642+
643+ // Watch runs a transactional function on the underlying client (not batched).
644+ func (ap * AutoPipeliner ) Watch (ctx context.Context , fn func (* Tx ) error , keys ... string ) error {
645+ return ap .pipeliner .Watch (ctx , fn , keys ... )
646+ }
647+
648+ // Subscribe opens a pub/sub on the underlying client (not batched — pub/sub
649+ // needs a dedicated connection).
650+ func (ap * AutoPipeliner ) Subscribe (ctx context.Context , channels ... string ) * PubSub {
651+ return ap .pipeliner .Subscribe (ctx , channels ... )
652+ }
653+
654+ // PSubscribe opens a pattern pub/sub on the underlying client (not batched).
655+ func (ap * AutoPipeliner ) PSubscribe (ctx context.Context , channels ... string ) * PubSub {
656+ return ap .pipeliner .PSubscribe (ctx , channels ... )
657+ }
658+
659+ // SSubscribe opens a sharded pub/sub on the underlying client (not batched).
660+ func (ap * AutoPipeliner ) SSubscribe (ctx context.Context , channels ... string ) * PubSub {
661+ return ap .pipeliner .SSubscribe (ctx , channels ... )
662+ }
663+
664+ // PoolStats returns the underlying client's connection pool statistics.
665+ func (ap * AutoPipeliner ) PoolStats () * PoolStats { return ap .pipeliner .PoolStats () }
666+
667+ // AutoPipeline delegates to the underlying client, which returns its cached
668+ // autopipeliner (typically this same instance). Present to satisfy the
669+ // UniversalClient surface.
670+ func (ap * AutoPipeliner ) AutoPipeline (config ... * AutoPipelineConfig ) (* AutoPipeliner , error ) {
671+ return ap .pipeliner .AutoPipeline (config ... )
672+ }
673+
674+ // AsyncAutoPipeline delegates to the underlying client. Present to satisfy the
675+ // UniversalClient surface.
676+ func (ap * AutoPipeliner ) AsyncAutoPipeline (config ... * AutoPipelineConfig ) (* AutoPipeliner , error ) {
677+ return ap .pipeliner .AsyncAutoPipeline (config ... )
678+ }
679+
680+ // validate AutoPipeliner implements UniversalClient (drop-in for the real
681+ // clients; non-data operations delegate to the underlying client).
682+ var _ UniversalClient = (* AutoPipeliner )(nil )
683+
627684// AutoFuture is the handle returned by Submit. Call Wait (or Result on the
628685// command after Wait) once the result is needed; it blocks only until the
629686// command's batch has executed.
0 commit comments