diff --git a/capnp/helpers/asyncHelper.h b/capnp/helpers/asyncHelper.h index 9d3860a..6bfef0b 100644 --- a/capnp/helpers/asyncHelper.h +++ b/capnp/helpers/asyncHelper.h @@ -31,3 +31,7 @@ private: void waitNeverDone(kj::WaitScope & scope) { kj::NEVER_DONE.wait(scope); } + +kj::Timer * getTimer(kj::AsyncIoContext * context) { + return &context->lowLevelProvider->getTimer(); +} diff --git a/capnp/helpers/helpers.pxd b/capnp/helpers/helpers.pxd index bdca969..fe5b7c6 100644 --- a/capnp/helpers/helpers.pxd +++ b/capnp/helpers/helpers.pxd @@ -1,4 +1,4 @@ -from .capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, PyRestorer, AnyPointer, DynamicStruct_Builder, WaitScope, AsyncIoContext, StringPtr, TaskSet +from .capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, PyRestorer, AnyPointer, DynamicStruct_Builder, WaitScope, AsyncIoContext, StringPtr, TaskSet, Timer from .capnp.includes.schema_cpp cimport ByteArray @@ -38,3 +38,4 @@ cdef extern from "../helpers/serialize.h": cdef extern from "../helpers/asyncHelper.h": void waitNeverDone(WaitScope&) + Timer * getTimer(AsyncIoContext *) diff --git a/capnp/includes/capnp_cpp.pxd b/capnp/includes/capnp_cpp.pxd index 0a76a3d..0d264fa 100644 --- a/capnp/includes/capnp_cpp.pxd +++ b/capnp/includes/capnp_cpp.pxd @@ -100,6 +100,16 @@ cdef extern from "kj/array.h" namespace " ::kj": ctypedef Promise[PyArray] PyPromiseArray +cdef extern from "kj/time.h" namespace " ::kj": + cdef cppclass Duration: + Duration(int64_t) + # cdef cppclass TimePoint: + # TimePoint(Duration) + cdef cppclass Timer: + # int64_t now() + # VoidPromise atTime(TimePoint time) + VoidPromise afterDelay(Duration delay) + cdef extern from "kj/async-io.h" namespace " ::kj": cdef cppclass AsyncIoStream: pass @@ -107,6 +117,7 @@ cdef extern from "kj/async-io.h" namespace " ::kj": # Own[AsyncInputStream] wrapInputFd(int) # Own[AsyncOutputStream] wrapOutputFd(int) Own[AsyncIoStream] wrapSocketFd(int) + Timer& getTimer() except +reraise_kj_exception cdef cppclass AsyncIoProvider: pass cdef cppclass WaitScope: diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 7ba44cf..0a166ca 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -1350,6 +1350,19 @@ cdef _EventLoop C_DEFAULT_EVENT_LOOP_GETTER(): raise RuntimeError("You don't have any EventLoops running. Please make sure to add one") +cdef class Timer: + cdef capnp.Timer * thisptr + + cdef _init(self, capnp.Timer * timer): + self.thisptr = timer + return self + + cpdef after_delay(self, time): + return _VoidPromise()._init(self.thisptr.afterDelay(capnp.Duration(time))) + +def getTimer(): + return Timer()._init(helpers.getTimer(C_DEFAULT_EVENT_LOOP_GETTER().thisptr)) + # cpdef remove_event_loop(): # 'Remove the global event loop' # global C_DEFAULT_EVENT_LOOP diff --git a/test/test_capability.py b/test/test_capability.py index f6f007d..b5de8a6 100644 --- a/test/test_capability.py +++ b/test/test_capability.py @@ -254,4 +254,16 @@ def test_tail_call(): assert result.n == 2 assert callee_server.count == 1 - assert caller_server.count == 1 \ No newline at end of file + assert caller_server.count == 1 + + +def test_timer(): + global test_timer_var + test_timer_var = False + + def set_timer_var(): + global test_timer_var + test_timer_var = True + capnp.getTimer().after_delay(1).then(set_timer_var).wait() + + assert test_timer_var is True