def testRefEqualitySettled(self): with scopedVat(testingVat()): first, r = makePromise() r.resolve(IntObject(42)) second, r = makePromise() r.resolve(IntObject(42)) self.assertEqual(optSame(first, second), EQUAL)
def recv(self, atom, args): from typhon.objects.collections.maps import EMPTY_MAP if atom is FROMNOW_1: duration = promoteToDouble(args[0]) p, r = makePromise() vat = currentVat.get() uv_timer = ruv.alloc_timer(vat.uv_loop) # Stash the resolver. ruv.stashTimer(uv_timer, (vat, r)) # repeat of 0 means "don't repeat" ruv.timerStart(uv_timer, resolveTimer, int(duration * 1000), 0) assert ruv.isActive(uv_timer), "Timer isn't active!?" return p if atom is TRIAL_1: obj = args[0] then = time.time() obj.call(u"run", []) now = time.time() # We can't give the value up immediately, due to determinism # requirements. Instead, provide it as a promise which will be # available on subsequent turns. rv = DoubleObject(now - then) p, r = makePromise() vat = currentVat.get() vat.sendOnly(r, RESOLVE_1, [rv], EMPTY_MAP) return p raise Refused(self, atom, args)
def testSwitchableChains(self): with scopedVat(testingVat()): p, r = makePromise() p2, r2 = makePromise() r.resolve(p2) self.assertFalse(isResolved(p)) r2.resolve(IntObject(42)) self.assertTrue(isResolved(p))
def run(self, sink): if self._closed: # Surprisingly, we do *not* need to throw here; we can simply # indicate that we're already done. from typhon.objects.collections.maps import EMPTY_MAP if self._failure is None: return self._vat.send(sink, COMPLETE_0, [], EMPTY_MAP) else: return self._vat.send(sink, ABORT_1, [self._failure], EMPTY_MAP) p, r = makePromise() self._queue.append((r, sink)) with io: try: data = ruv.magic_readStart(self._stream._stream) except object as err: sendAllSinks(self, ABORT_1, [StrObject(u"libuv error: %s" % err)]) cleanup(self) else: if data == "": sendAllSinks(self, COMPLETE_0, []) cleanup(self) else: sendNextSink(self, RUN_1, [BytesObject(data)]) return p
def testSwitchableBecomesResolved(self): with scopedVat(testingVat()): p, r = makePromise() self.assertFalse(isResolved(p)) r.resolve(IntObject(42)) self.assertTrue(isResolved(p))
def setContents(self, data): sibling = self.temporarySibling(".setContents") p, r = makePromise() vat = currentVat.get() path = sibling.asBytes() # Use CREAT | EXCL to cause a failure if the temporary file # already exists. flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL with io: f = 0 try: f = ruv.magic_fsOpen(vat, path, flags, 0777) except object as err: smash(r, StrObject(u"Couldn't open file fount: %s" % err)) else: try: writeLoop(f, data) except object as err: ruv.magic_fsClose(vat, f) smash(r, StrObject(u"libuv error: %s" % err)) else: ruv.magic_fsClose(vat, f) ruv.magic_fsRename(vat, path, self.asBytes()) resolve(r, NullObject) return p
def wait(self): p, r = makePromise() if self.exit_and_signal != self.EMPTY_EXIT_AND_SIGNAL: self.resolveWaiter(r) else: self.resolvers.append(r) return p
def connect(self): vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) fount, fountResolver = makePromise() drain, drainResolver = makePromise() # Ugh, the hax. resolvers = ConstList([fountResolver, drainResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) # Make the actual connection. ruv.tcpConnect(stream, self.host, self.port, connectCB) # Return the promises. return ConstList([fount, drain])
def connect(self): vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) fount, fountResolver = makePromise() drain, drainResolver = makePromise() # Ugh, the hax. resolvers = wrapList([fountResolver, drainResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) # Make the actual connection. ruv.tcpConnect(stream, self.host, self.port, connectCB) # Return the promises. return [fount, drain]
def connectStream(self): vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) source, sourceResolver = makePromise() sink, sinkResolver = makePromise() # Ugh, the hax. resolvers = wrapList([sourceResolver, sinkResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) # Make the actual connection. ruv.tcpConnect(stream, self.host, self.port, connectStreamCB) # Return the promises. return [source, sink]
def run(self, sink): p, r = makePromise() self._queue.append((r, sink)) with scoped_alloc(ruv.rffi.CArray(ruv.buf_t), 1) as bufs: bufs[0].c_base = self._buf.c_base bufs[0].c_len = self._buf.c_len ruv.fsRead(self._vat.uv_loop, self._fs, self._fd, bufs, 1, -1, readFileCB) return p
def send(self, target, atom, args, namedArgs): from typhon.objects.refs import makePromise promise, resolver = makePromise() with self._pendingLock: self._pending.append((resolver, target, atom, args, namedArgs)) self.log(u"Planning to send: %s<-%s(%s) (resolver: yes)" % (target.toQuote(), atom.verb, u", ".join([arg.toQuote() for arg in args]))) return promise
def send(self, target, atom, args, namedArgs): from typhon.objects.refs import makePromise promise, resolver = makePromise() with self._pendingLock: self._pending.append((resolver, target, atom, args, namedArgs)) # self.log(u"Planning to send: %s<-%s(%s) (resolver: yes)" % # (target.toQuote(), atom.verb, # u", ".join([arg.toQuote() for arg in args]))) return promise
def connectStream(self): """ Connect this endpoint, returning a `[source, sink]` pair.of vows. """ vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) source, sourceResolver = makePromise() sink, sinkResolver = makePromise() # Ugh, the hax. resolvers = wrapList([sourceResolver, sinkResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) vat.enqueueEvent(ConnectStreamIOEvent( vat, stream, self.host, self.port, self.inet_type)) # Return the promises. return [source, sink]
def getAddrInfo(node, service): node = unwrapBytes(node) service = unwrapBytes(service) vat = currentVat.get() gai = ruv.alloc_gai() p, r = makePromise() ruv.stashGAI(gai, (vat, r)) ruv.getAddrInfo(vat.uv_loop, gai, gaiCB, node, service, nullptr(ruv.s.addrinfo)) return p
def rename(self, dest): p, r = makePromise() vat = currentVat.get() uv_loop = vat.uv_loop fs = ruv.alloc_fs() src = self.asBytes() ruv.stashFS(fs, (vat, r)) ruv.fsRename(uv_loop, fs, src, dest, renameCB) return p
def fromNow(self, duration): p, r = makePromise() vat = currentVat.get() uv_timer = ruv.alloc_timer(vat.uv_loop) now = ruv.now(vat.uv_loop) # Stash the resolver. ruv.stashTimer(uv_timer, (vat, (r, now))) # repeat of 0 means "don't repeat" ruv.timerStart(uv_timer, resolveTimer, int(duration * 1000), 0) return p
def run(self, sink): p, r = makePromise() self._queue.append((r, sink)) with scoped_alloc(ruv.rffi.CArray(ruv.buf_t), 1) as bufs: bufs[0].c_base = self._buf.c_base bufs[0].c_len = self._buf.c_len fs = ruv.alloc_fs() ruv.stashFS(fs, (self._vat, self)) ruv.fsRead(self._vat.uv_loop, fs, self._fd, bufs, 1, -1, readFileCB) return p
def connectStream(self): """ Connect this endpoint, returning a `[source, sink]` pair.of vows. """ vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) source, sourceResolver = makePromise() sink, sinkResolver = makePromise() # Ugh, the hax. resolvers = wrapList([sourceResolver, sinkResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) # Make the actual connection. if self.inet_type == 4: ruv.tcp4Connect(stream, self.host, self.port, connectStreamCB) elif self.inet_type == 6: ruv.tcp6Connect(stream, self.host, self.port, connectStreamCB) # Return the promises. return [source, sink]
def rename(self, fr): if not isinstance(fr, FileResource): raise userError(u"rename/1: Must be file resource") dest = fr.asBytes() p, r = makePromise() vat = currentVat.get() with io: try: ruv.magic_fsRename(vat, self.asBytes(), dest) except object as err: smash(r, StrObject(u"Couldn't rename file: %s" % err)) else: resolve(r, NullObject) return p
def recv(self, atom, args): if atom is GETCONTENTS_0: return self.open(openGetContentsCB, flags=os.O_RDONLY, mode=0000) if atom is SETCONTENTS_1: data = unwrapBytes(args[0]) sibling = self.temporarySibling(".setContents") p, r = makePromise() vat = currentVat.get() uv_loop = vat.uv_loop fs = ruv.alloc_fs() path = sibling.asBytes() # Use CREAT | EXCL to cause a failure if the temporary file # already exists. flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL sc = SetContents(vat, data, r, sibling, self) ruv.stashFS(fs, (vat, sc)) ruv.fsOpen(uv_loop, fs, path, flags, 0777, openSetContentsCB) return p if atom is OPENFOUNT_0: return self.open(openFountCB, flags=os.O_RDONLY, mode=0000) if atom is OPENDRAIN_0: # Create the file if it doesn't yet exist, and truncate it if it # does. Trust the umask to be reasonable for now. flags = os.O_CREAT | os.O_WRONLY # XXX this behavior should be configurable via namedarg? flags |= os.O_TRUNC return self.open(openDrainCB, flags=flags, mode=0777) if atom is RENAME_1: fr = args[0] if not isinstance(fr, FileResource): raise userError(u"rename/1: Must be file resource") return self.rename(fr.asBytes()) if atom is SIBLING_1: name = unwrapStr(args[0]) if u'/' in name: raise userError(u"sibling/1: Illegal file name '%s'" % name) return self.sibling(name.encode("utf-8")) if atom is TEMPORARYSIBLING_0: return self.temporarySibling(".new") raise Refused(self, atom, args)
def open(self, callback, flags=None, mode=None): # Always call this as .open(callback, flags=..., mode=...) assert flags is not None assert mode is not None p, r = makePromise() vat = currentVat.get() uv_loop = vat.uv_loop fs = ruv.alloc_fs() path = self.asBytes() log.log(["fs"], u"makeFileResource: Opening file '%s'" % path.decode("utf-8")) ruv.stashFS(fs, (vat, r)) ruv.fsOpen(uv_loop, fs, path, flags, mode, callback) return p
def run(self, sink): if self._closed: # Surprisingly, we do *not* need to throw here; we can simply # indicate that we're already done. from typhon.objects.collections.maps import EMPTY_MAP if self._failure is None: return self._vat.send(sink, COMPLETE_0, [], EMPTY_MAP) else: return self._vat.send(sink, ABORT_1, [self._failure], EMPTY_MAP) p, r = makePromise() self._queue.append((r, sink)) ruv.readStart(self._stream._stream, ruv.allocCB, readStreamCB) return p
def getAddrInfo(node, service): node = unwrapBytes(node) service = unwrapBytes(service) vat = currentVat.get() p, r = makePromise() emptyAI = nullptr(ruv.s.addrinfo) with io: ai = emptyAI try: ai = ruv.magic_getAddrInfo(vat, node, service) except object as err: smash(r, StrObject(u"libuv error: %s" % err)) else: resolve(r, wrapList(walkAI(ai)[:])) return p
def setContents(self, data): sibling = self.temporarySibling(".setContents") p, r = makePromise() vat = currentVat.get() uv_loop = vat.uv_loop fs = ruv.alloc_fs() path = sibling.asBytes() # Use CREAT | EXCL to cause a failure if the temporary file # already exists. flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL sc = SetContents(vat, data, r, sibling, self) ruv.stashFS(fs, (vat, sc)) ruv.fsOpen(uv_loop, fs, path, flags, 0777, openSetContentsCB) return p
def run(self, sink): p, r = makePromise() self._queue.append((r, sink)) # XXX long handwavey explanation of io macro limitations vs rpython # type unification here vat, fd, buf = self._vat, self._fd, self._buf with io: try: data = ruv.magic_fsRead(vat, fd, buf) except object as err: sendAllSinks(self, ABORT_1, [StrObject(u"libuv error: %s" % err)]) ruv.magic_fsClose(self._vat, self._fd) cleanup(self) else: if data == "": sendAllSinks(self, COMPLETE_0, []) ruv.magic_fsClose(self._vat, self._fd) else: sendNextSink(self, RUN_1, [BytesObject(data)]) return p
def getContents(self): p, r = makePromise() vat = currentVat.get() buf = ruv.allocBuf(16384) path = self.asBytes() log.log(["fs"], u"makeFileResource: Opening file '%s'" % path.decode("utf-8")) with io: f = 0 try: f = ruv.magic_fsOpen(vat, path, os.O_RDONLY, 0000) except object as err: smash(r, StrObject(u"Couldn't open file fount: %s" % err)) else: try: contents = readLoop(f, buf) except object as err: ruv.magic_fsClose(vat, f) smash(r, StrObject(u"libuv error: %s" % err)) else: ruv.magic_fsClose(vat, f) resolve(r, BytesObject(contents)) return p
def recv(self, atom, args): from typhon.objects.collections.maps import EMPTY_MAP if atom is UNSAFENOW_0: return DoubleObject(time.time()) if atom is FROMNOW_1: duration = promoteToDouble(args[0]) p, r = makePromise() vat = currentVat.get() uv_timer = ruv.alloc_timer(vat.uv_loop) # Stash the resolver. ruv.stashTimer(uv_timer, (vat, r)) # repeat of 0 means "don't repeat" ruv.timerStart(uv_timer, resolveTimer, int(duration * 1000), 0) assert ruv.isActive(uv_timer), "Timer isn't active!?" return p if atom is SENDTIMESTAMP_1: now = time.time() vat = currentVat.get() return vat.send(args[0], RUN_1, [DoubleObject(now)], EMPTY_MAP) raise Refused(self, atom, args)
def fromNow(self, duration): p, r = makePromise() vat = currentVat.get() vat.enqueueEvent(TimerIOEvent(vat, r, duration)) return p
def testRefEqualityReflexive(self): with scopedVat(testingVat()): p, r = makePromise() self.assertEqual(optSame(p, p), EQUAL)
def testRefEquality(self): with scopedVat(testingVat()): first, r = makePromise() second, r = makePromise() self.assertEqual(optSame(first, second), NOTYET)
def testPromise(self): with scopedVat(testingVat()): p, r = makePromise() self.assertFalse(isSettled(p))
def testPromiseResolved(self): with scopedVat(testingVat()): p, r = makePromise() r.resolve(IntObject(42)) self.assertTrue(isSettled(p))
def testPromise(self): with scopedVat(testingVat()): p, r = makePromise() self.assertFalse(p.isSettled())
def testPromiseResolved(self): with scopedVat(testingVat()): p, r = makePromise() r.resolve(IntObject(42)) self.assertTrue(p.isSettled())
def makeNear(o): p, r = makePromise() r.resolve(o) return p