Poll for market open instead of single long setTimeout

macOS sleep suspends the Docker VM, causing long setTimeout calls to
never fire. Replace the one-shot wait with a polling loop that checks
getClock every 30s (capped to time-until-open), so the bot resumes
promptly after the host wakes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jon
2026-02-11 11:02:49 -07:00
parent 46e7bef4b2
commit 7b1a20c768
3 changed files with 59 additions and 20 deletions

View File

@@ -69,17 +69,36 @@ describe('waitForNextOpen', () => {
vi.spyOn(console, 'debug').mockImplementation(() => {});
});
it('calls getClock and waits until next_open', async () => {
it('polls until market opens', async () => {
const futureDate = new Date(Date.now() + 60000).toISOString();
const alpaca = mockAlpaca({
getClock: vi.fn().mockResolvedValue({ is_open: false, next_open: futureDate, next_close: futureDate }),
getClock: vi.fn()
.mockResolvedValueOnce({ is_open: false, next_open: futureDate, next_close: futureDate })
.mockResolvedValueOnce({ is_open: false, next_open: futureDate, next_close: futureDate })
.mockResolvedValueOnce({ is_open: true, next_open: futureDate, next_close: futureDate }),
});
const promise = waitForNextOpen(alpaca);
await vi.advanceTimersByTimeAsync(60000);
const promise = waitForNextOpen(alpaca, 100);
await vi.advanceTimersByTimeAsync(300);
await promise;
expect(alpaca.getClock).toHaveBeenCalled();
expect(alpaca.getClock).toHaveBeenCalledTimes(3);
});
it('sleeps at most pollInterval even when open is far away', async () => {
const farFuture = new Date(Date.now() + 86_400_000).toISOString();
const alpaca = mockAlpaca({
getClock: vi.fn()
.mockResolvedValueOnce({ is_open: false, next_open: farFuture, next_close: farFuture })
.mockResolvedValueOnce({ is_open: true, next_open: farFuture, next_close: farFuture }),
});
const promise = waitForNextOpen(alpaca, 200);
await vi.advanceTimersByTimeAsync(300);
await promise;
// Should have polled twice: first sleep capped to 200ms, then saw is_open
expect(alpaca.getClock).toHaveBeenCalledTimes(2);
});
});