44
55use Carbon \Carbon ;
66use Carbon \CarbonInterface ;
7+ use Closure ;
78use DirectoryTree \ImapEngine \Connection \Responses \UntaggedResponse ;
89use DirectoryTree \ImapEngine \Exceptions \Exception ;
910use DirectoryTree \ImapEngine \Exceptions \ImapConnectionClosedException ;
@@ -18,7 +19,7 @@ class Idle
1819 public function __construct (
1920 protected Mailbox $ mailbox ,
2021 protected string $ folder ,
21- protected int $ timeout ,
22+ protected Closure | int $ timeout ,
2223 ) {}
2324
2425 /**
@@ -36,10 +37,7 @@ public function await(callable $callback): void
3637 {
3738 $ this ->connect ();
3839
39- // Loop indefinitely, restarting IDLE sessions as needed.
40- while (true ) {
41- $ ttl = $ this ->getNextTimeout ();
42-
40+ while ($ ttl = $ this ->getNextTimeout ()) {
4341 try {
4442 $ this ->listen ($ callback , $ ttl );
4543 } catch (ImapConnectionTimedOutException ) {
@@ -56,7 +54,7 @@ public function await(callable $callback): void
5654 protected function listen (callable $ callback , CarbonInterface $ ttl ): void
5755 {
5856 // Iterate over responses yielded by the idle generator.
59- foreach ($ this ->idle () as $ response ) {
57+ foreach ($ this ->idle ($ ttl ) as $ response ) {
6058 if (! $ response instanceof UntaggedResponse) {
6159 continue ;
6260 }
@@ -69,6 +67,10 @@ protected function listen(callable $callback, CarbonInterface $ttl): void
6967 $ ttl = $ this ->getNextTimeout ();
7068 }
7169
70+ if ($ ttl === false ) {
71+ break ;
72+ }
73+
7274 // If we've been idle too long, break out to restart the session.
7375 if (Carbon::now ()->greaterThanOrEqualTo ($ ttl )) {
7476 $ this ->restart ();
@@ -145,16 +147,22 @@ protected function done(): void
145147 /**
146148 * Begin a new IDLE session as a generator.
147149 */
148- protected function idle (): Generator
150+ protected function idle (CarbonInterface $ ttl ): Generator
149151 {
150- yield from $ this ->mailbox ->connection ()->idle ($ this ->timeout );
152+ yield from $ this ->mailbox ->connection ()->idle (
153+ (int ) Carbon::now ()->diffInSeconds ($ ttl , true )
154+ );
151155 }
152156
153157 /**
154158 * Get the next timeout as a Carbon instance.
155159 */
156- protected function getNextTimeout (): CarbonInterface
160+ protected function getNextTimeout (): CarbonInterface | false
157161 {
158- return Carbon::now ()->addSeconds ($ this ->timeout );
162+ if (is_numeric ($ seconds = value ($ this ->timeout ))) {
163+ return Carbon::now ()->addSeconds (abs ($ seconds ));
164+ }
165+
166+ return false ;
159167 }
160168}
0 commit comments