@@ -35,8 +35,11 @@ class Adapter
3535 /** @var array<string, array{inbound: int, outbound: int}> Byte counters per resource since last flush */
3636 protected array $ byteCounters = [];
3737
38+ /** @var \Closure|null Custom resolve callback, checked before the resolver */
39+ protected ?\Closure $ resolveCallback = null ;
40+
3841 public function __construct (
39- public Resolver $ resolver {
42+ public ? Resolver $ resolver = null {
4043 get {
4144 return $ this ->resolver ;
4245 }
@@ -58,6 +61,18 @@ public function setActivityInterval(int $seconds): static
5861 return $ this ;
5962 }
6063
64+ /**
65+ * Set a custom resolve callback that is checked before the resolver
66+ *
67+ * The callback receives a resource ID and should return a Resolver\Result.
68+ */
69+ public function onResolve (callable $ callback ): static
70+ {
71+ $ this ->resolveCallback = $ callback (...);
72+
73+ return $ this ;
74+ }
75+
6176 /**
6277 * Skip SSRF validation for trusted backends
6378 */
@@ -75,7 +90,7 @@ public function setSkipValidation(bool $skip): static
7590 */
7691 public function notifyConnect (string $ resourceId , array $ metadata = []): void
7792 {
78- $ this ->resolver ->onConnect ($ resourceId , $ metadata );
93+ $ this ->resolver ? ->onConnect($ resourceId , $ metadata );
7994 }
8095
8196 /**
@@ -92,7 +107,7 @@ public function notifyClose(string $resourceId, array $metadata = []): void
92107 unset($ this ->byteCounters [$ resourceId ]);
93108 }
94109
95- $ this ->resolver ->onDisconnect ($ resourceId , $ metadata );
110+ $ this ->resolver ? ->onDisconnect($ resourceId , $ metadata );
96111 unset($ this ->lastActivityUpdate [$ resourceId ]);
97112 }
98113
@@ -133,7 +148,7 @@ public function track(string $resourceId, array $metadata = []): void
133148 $ this ->byteCounters [$ resourceId ] = ['inbound ' => 0 , 'outbound ' => 0 ];
134149 }
135150
136- $ this ->resolver ->track ($ resourceId , $ metadata );
151+ $ this ->resolver ? ->track($ resourceId , $ metadata );
137152 }
138153
139154 /**
@@ -190,7 +205,19 @@ public function route(string $resourceId): ConnectionResult
190205 $ this ->stats ['cacheMisses ' ]++;
191206
192207 try {
193- $ result = $ this ->resolver ->resolve ($ resourceId );
208+ if ($ this ->resolveCallback !== null ) {
209+ $ resolved = ($ this ->resolveCallback )($ resourceId );
210+ $ result = $ resolved instanceof Resolver \Result
211+ ? $ resolved
212+ : new Resolver \Result (endpoint: (string ) $ resolved );
213+ } elseif ($ this ->resolver !== null ) {
214+ $ result = $ this ->resolver ->resolve ($ resourceId );
215+ } else {
216+ throw new ResolverException (
217+ "No resolver or resolve callback configured " ,
218+ ResolverException::NOT_FOUND
219+ );
220+ }
194221 $ endpoint = $ result ->endpoint ;
195222
196223 if (empty ($ endpoint )) {
@@ -307,7 +334,7 @@ public function getStats(): array
307334 'routingErrors ' => $ this ->stats ['routingErrors ' ],
308335 'routingTableMemory ' => $ this ->router ->memorySize ,
309336 'routingTableSize ' => $ this ->router ->count (),
310- 'resolver ' => $ this ->resolver ->getStats (),
337+ 'resolver ' => $ this ->resolver ? ->getStats() ?? [] ,
311338 ];
312339 }
313340}
0 commit comments