clockport

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: MIT Imports: 2 Imported by: 0

README

kite-mcp-clockport

Go Reference

Clock + Ticker port interfaces for the algo2go ecosystem. Pure stdlib leaf hosting the time-source abstraction with RealClock zero-value default. Production code that needs to be testable without wall-clock waits imports this module; in-memory test fakes (FakeClock, fakeTicker, NewFakeClock) live in Sundeepg98/kite-mcp-server's testutil package because they are genuinely test-only.

Why a separate module?

The original port + RealClock + FakeClock all lived in testutil/clock.go — but production reverse-deps (e.g., kc/fill_watcher.go) had to import testutil just to reach the port, inverting the typical "test helpers, never imported by production" naming. This module separates the production-clean port from the test-only fakes:

  • Centralizes the Clock + Ticker contract for any algo2go consumer needing a testable time abstraction
  • Eliminates the "production imports testutil" misnomer in consumer codebases
  • Keeps the test fakes adjacent to consumer tests (testutil) where Go conventions expect them

Stability promise

v0.x — unstable. Pin v0.1.0 deliberately.

Install

go get github.com/algo2go/kite-mcp-clockport@v0.1.0

Public API

type Clock interface {
    Now() time.Time
    NewTicker(d time.Duration) Ticker
}

type Ticker interface {
    C() <-chan time.Time
    Stop()
}

type RealClock struct{}    // zero-value default; production

RealClock{} returns time.Now() and wraps time.NewTicker. In tests, swap it for any structurally-compatible fake — e.g., testutil.NewFakeClock(t) from Sundeepg98/kite-mcp-server's testutil package.

What this port does NOT help with

  • Sleeps waiting for external I/O (TCP bind, HTTP server readiness, SQLite worker drain). A fake clock cannot speed up the OS bind; those sleeps belong to integration-test scope.
  • Time-based business rules in the domain layer (order expiry, market-hours gates). Those should wrap their own domain-level abstractions if they need fake-clock coverage.

Dependencies

  • NONE at runtime (pure stdlib sync + time)
  • github.com/stretchr/testify v1.10.0 (test-only)

Joins kite-mcp-sectors and kite-mcp-isttz as the third zero-deps algo2go module.

Reference consumer

Sundeepg98/kite-mcp-server — consumed in kc/fill_watcher.go (production: real-flow bridge for domain.OrderFilledEvent polling) and app/ratelimit_cleanup_test.go (test adapter for rate-limiter cleanup goroutine driving). The matching testutil.FakeClock lives at Sundeepg98/kite-mcp-server/testutil/clock.go and structurally satisfies clockport.Clock via Go duck typing.

License

MIT — see LICENSE.

Authors

Original port design: Sundeepg98 (Zerodha Tech), originally located in testutil/clock.go. Multi-module promotion (2026-05-10): algo2go contributors.

Path A inauguration arc

This is the 28th algo2go module. The Path A.1-A.26 arc closed at 27 modules with kc/sectors A.26 (the final extractable kc/* module). Path A.27 extends the arc by 1 to address the testutil-misnaming problem properly: the production port is now external, separate from the test fakes.

The matching halt findings (which led to this module) are documented in .research/testutil-clock-port-split-design.md in the reference consumer's repo (commit fa6c70a in Sundeepg98/kite-mcp-server).

Documentation

Overview

Package clockport provides a minimal time-source port that production code can depend on without coupling to wall-clock behavior. The matching in-memory test fakes (FakeClock) live in github.com/zerodha/kite-mcp-server/testutil — a deliberate split: the production interface stays infrastructure-clean (zero algo2go deps, pure stdlib), while the test fakes stay where Go conventions expect them (a testutil package adjacent to the consumer's tests).

Architectural rationale: Production reverse-deps that previously imported testutil just to reach `testutil.Clock`/`testutil.Ticker`/`testutil.RealClock{}` (e.g., kc/fill_watcher.go in the kite-mcp-server reference consumer) now import this module instead. testutil retains FakeClock + fakeTicker + NewFakeClock (genuinely test-only). The split eliminates the "test helpers used in production paths" misnomer.

What this port does NOT help with:

  • Sleeps that wait for external I/O (TCP bind, HTTP server readiness, SQLite worker drain). A fake clock cannot make the OS bind faster; those sleeps stay and belong to integration-test scope.
  • Time-based business rules expressed in the domain layer (e.g., order expiry windows, market-hours gates). Those should be wrapped by their own domain-level abstractions if they need fake-clock coverage.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Clock

type Clock interface {
	// Now returns the current time as perceived by this clock.
	Now() time.Time
	// NewTicker returns a Ticker that fires at the given interval. Stop
	// must be called by the caller to release resources.
	NewTicker(d time.Duration) Ticker
}

Clock is the minimal time-source port. The two methods we need today are Now (wall time) and NewTicker (a channel that fires at intervals). Callers who also need Sleep can layer it on top of NewTicker + receive.

type RealClock

type RealClock struct{}

RealClock is the production clock. Zero-value is ready to use; no constructor needed.

func (RealClock) NewTicker

func (RealClock) NewTicker(d time.Duration) Ticker

NewTicker returns a real time.Ticker wrapped to satisfy the Ticker interface.

func (RealClock) Now

func (RealClock) Now() time.Time

Now returns time.Now().

type Ticker

type Ticker interface {
	// C returns the channel on which ticks are delivered.
	C() <-chan time.Time
	// Stop stops the ticker. It is safe to call multiple times.
	Stop()
}

Ticker abstracts the tick channel + Stop pair. The real implementation wraps *time.Ticker; fake implementations (e.g., github.com/zerodha/kite-mcp-server/testutil.FakeClock's fakeTicker) deliver ticks when their Advance method crosses the interval boundary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL