99use ReactParallel \ObjectProxy \Generated \ProxyList ;
1010use ReactParallel \ObjectProxy \Message \Call ;
1111use ReactParallel \ObjectProxy \Message \Destruct ;
12+ use ReactParallel \ObjectProxy \Proxy \Instance ;
1213use WyriHaximus \Metrics \Label ;
1314use WyriHaximus \Metrics \Registry ;
1415use WyriHaximus \Metrics \Registry \Counters ;
@@ -30,7 +31,7 @@ final class Proxy extends ProxyList
3031
3132 private Channel $ in ;
3233
33- /** @var array<string, object > */
34+ /** @var array<string, Instance > */
3435 private array $ instances = [];
3536
3637 /** @var array<string, string|false> */
@@ -61,6 +62,7 @@ public function withMetrics(Registry $registry): self
6162 $ self ->counterDestruct = $ registry ->counter (
6263 'react_parallel_object_proxy_destruct ' ,
6364 'Number of destroyed proxies by the garbage collector ' ,
65+ new Label \Name ('class ' ),
6466 new Label \Name ('interface ' ),
6567 );
6668 $ self ->in = new Channel (Channel::Infinite);
@@ -80,14 +82,14 @@ public function create(object $object, string $interface): object
8082 throw NonExistentInterface::create ($ interface );
8183 }
8284
83- if ($ this ->counterCreate instanceof Counters) {
84- $ this ->counterCreate ->counter (new Label ('class ' , get_class ($ object )), new Label ('interface ' , $ interface ))->incr ();
85- }
86-
8785 $ class = self ::KNOWN_INTERFACE [$ interface ];
8886 $ hash = bin2hex (random_bytes (13 ));
8987
90- $ this ->instances [$ hash ] = $ object ;
88+ $ this ->instances [$ hash ] = new Instance ($ object , $ interface );
89+
90+ if ($ this ->counterCreate instanceof Counters) {
91+ $ this ->counterCreate ->counter (new Label ('class ' , $ this ->instances [$ hash ]->class ()), new Label ('interface ' , $ interface ))->incr ();
92+ }
9193
9294 /** @psalm-suppress InvalidStringClass */
9395 return new $ class ($ this ->in , $ hash );
@@ -117,13 +119,18 @@ private function setUpHandlers(): void
117119
118120 private function handleCall (Call $ call ): void
119121 {
120- $ object = $ this ->instances [$ call ->hash ()];
122+ if (! array_key_exists ($ call ->hash (), $ this ->instances )) {
123+ return ;
124+ }
125+
126+ $ instance = $ this ->instances [$ call ->hash ()];
127+ $ instance ->reference ($ call ->objectHash ());
121128 if ($ this ->counterCall instanceof Counters) {
122- $ this ->counterCall ->counter (new Label ('class ' , get_class ( $ object )), new Label ('interface ' , $ call ->interface ()))->incr ();
129+ $ this ->counterCall ->counter (new Label ('class ' , $ instance -> class ( )), new Label ('interface ' , $ instance ->interface ()))->incr ();
123130 }
124131
125132 /** @phpstan-ignore-next-line */
126- $ outcome = $ object ->{$ call ->method ()}(...$ call ->args ());
133+ $ outcome = $ instance -> object () ->{$ call ->method ()}(...$ call ->args ());
127134
128135 if (is_object ($ outcome )) {
129136 $ outcomeClass = get_class ($ outcome );
@@ -142,13 +149,21 @@ private function handleCall(Call $call): void
142149
143150 private function handleDestruct (Destruct $ destruct ): void
144151 {
145- unset($ this ->instances [$ destruct ->hash ()]);
152+ if (! array_key_exists ($ destruct ->hash (), $ this ->instances )) {
153+ return ;
154+ }
155+
156+ $ instance = $ this ->instances [$ destruct ->hash ()];
157+ $ count = $ instance ->dereference ($ destruct ->objectHash ());
158+ if ($ count === 0 ) {
159+ unset($ this ->instances [$ destruct ->hash ()]);
160+ }
146161
147162 if (! ($ this ->counterDestruct instanceof Counters)) {
148163 return ;
149164 }
150165
151- $ this ->counterDestruct ->counter (new Label ('interface ' , $ destruct ->interface ()))->incr ();
166+ $ this ->counterDestruct ->counter (new Label ('class ' , $ instance -> class ()), new Label ( ' interface ' , $ instance ->interface ()))->incr ();
152167 }
153168
154169 /** @phpstan-ignore-next-line */
0 commit comments