Commit cd6352dd authored by Arushi Aggarwal's avatar Arushi Aggarwal Committed by Facebook Github Bot

Add functions for bridging semi futures

Reviewed By: yfeldblum

Differential Revision: D14062156

fbshipit-source-id: 2cdc32fc9834bd165fa8011ca1d336edaf05f653
parent 7e209f43
...@@ -18,6 +18,10 @@ cdef extern from "folly/futures/Future.h" namespace "folly" nogil: ...@@ -18,6 +18,10 @@ cdef extern from "folly/futures/Future.h" namespace "folly" nogil:
cbool isReady() cbool isReady()
#TODO add via and then #TODO add via and then
cdef cppclass cFollySemiFuture "folly::SemiFuture"[T]:
T get()
pass
cdef extern from "folly/Unit.h" namespace "folly": cdef extern from "folly/Unit.h" namespace "folly":
struct cFollyUnit "folly::Unit": struct cFollyUnit "folly::Unit":
pass pass
......
...@@ -64,5 +64,24 @@ void bridgeFuture( ...@@ -64,5 +64,24 @@ void bridgeFuture(
getExecutor(), std::move(futureFrom), std::move(callback), userData); getExecutor(), std::move(futureFrom), std::move(callback), userData);
} }
template <typename T>
void bridgeSemiFuture(
folly::Executor* executor,
folly::SemiFuture<T>&& semiFutureFrom,
folly::Function<void(folly::Try<T>&&, PyObject*)> callback,
PyObject* userData) {
folly::Future<T> futureFrom = std::move(semiFutureFrom).via(executor);
bridgeFuture(executor, std::move(futureFrom), std::move(callback), userData);
}
template <typename T>
void bridgeSemiFuture(
folly::SemiFuture<T>&& semiFutureFrom,
folly::Function<void(folly::Try<T>&&, PyObject*)> callback,
PyObject* userData) {
bridgeSemiFuture(
getExecutor(), std::move(semiFutureFrom), std::move(callback), userData);
}
} // namespace python } // namespace python
} // namespace folly } // namespace folly
from cpython.ref cimport PyObject from cpython.ref cimport PyObject
from folly cimport cFollyTry, cFollyFuture, cFollyExecutor from folly cimport cFollyTry, cFollyFuture, cFollyExecutor, cFollySemiFuture
cdef extern from "folly/python/futures.h" namespace "folly::python": cdef extern from "folly/python/futures.h" namespace "folly::python":
void bridgeFuture[T]( void bridgeFuture[T](
...@@ -14,3 +14,15 @@ cdef extern from "folly/python/futures.h" namespace "folly::python": ...@@ -14,3 +14,15 @@ cdef extern from "folly/python/futures.h" namespace "folly::python":
void(*)(cFollyTry[T]&&, PyObject*), void(*)(cFollyTry[T]&&, PyObject*),
PyObject* pyFuture PyObject* pyFuture
) )
void bridgeSemiFuture[T](
cFollySemiFuture[T]&& fut,
void(*)(cFollyTry[T]&&, PyObject*),
PyObject* pyFuture
)
# No clue but cython overloading is getting confused so we alias
void bridgeSemiFutureWith "folly::python::bridgeSemiFuture"[T](
cFollyExecutor* executor,
cFollySemiFuture[T]&& fut,
void(*)(cFollyTry[T]&&, PyObject*),
PyObject* pyFuture
)
...@@ -12,6 +12,12 @@ class Futures(unittest.TestCase): ...@@ -12,6 +12,12 @@ class Futures(unittest.TestCase):
res = loop.run_until_complete(simplebridge.get_value_x5(val)) res = loop.run_until_complete(simplebridge.get_value_x5(val))
self.assertEqual(val * 5, res) self.assertEqual(val * 5, res)
def test_bridge_semifuture(self):
val = 1337
loop = asyncio.get_event_loop()
res = loop.run_until_complete(simplebridge.get_value_x5_semifuture(val))
self.assertEqual(val * 5, res)
def test_bridge_exception(self): def test_bridge_exception(self):
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
with self.assertRaises(ValueError, msg="0 is not allowed"): with self.assertRaises(ValueError, msg="0 is not allowed"):
......
...@@ -34,6 +34,18 @@ folly::Future<uint64_t> future_getValueX5(uint64_t val) { ...@@ -34,6 +34,18 @@ folly::Future<uint64_t> future_getValueX5(uint64_t val) {
return f; return f;
} }
folly::SemiFuture<uint64_t> semiFuture_getValueX5(uint64_t val) {
folly::Promise<uint64_t> p;
auto f = p.getSemiFuture();
p.setWith([val] {
if (val == 0) {
throw std::invalid_argument("0 is not allowed");
}
return val * 5;
});
return f;
}
folly::Function<uint64_t()> getValueX5Fibers(uint64_t val) { folly::Function<uint64_t()> getValueX5Fibers(uint64_t val) {
return [val]() { return [val]() {
if (val == 0) { if (val == 0) {
......
import asyncio import asyncio
from folly.futures cimport bridgeFuture from folly.futures cimport bridgeFuture, bridgeSemiFuture
from folly.fibers cimport bridgeFibers from folly.fibers cimport bridgeFibers
from folly cimport cFollyFuture, cFollyTry from folly cimport cFollyFuture, cFollySemiFuture, cFollyTry
from libc.stdint cimport uint64_t from libc.stdint cimport uint64_t
from cpython.ref cimport PyObject from cpython.ref cimport PyObject
from cython.operator cimport dereference as deref from cython.operator cimport dereference as deref
cdef extern from "folly/python/test/simple.h" namespace "folly::python::test": cdef extern from "folly/python/test/simple.h" namespace "folly::python::test":
cdef cFollyFuture[uint64_t] future_getValueX5(uint64_t val) cdef cFollyFuture[uint64_t] future_getValueX5(uint64_t val)
cdef cFollySemiFuture[uint64_t] semiFuture_getValueX5(uint64_t val)
cdef (uint64_t(*)()) getValueX5Fibers(uint64_t val) cdef (uint64_t(*)()) getValueX5Fibers(uint64_t val)
...@@ -21,6 +22,15 @@ def get_value_x5(int val): ...@@ -21,6 +22,15 @@ def get_value_x5(int val):
) )
return fut return fut
def get_value_x5_semifuture(int val):
loop = asyncio.get_event_loop()
fut = loop.create_future()
bridgeSemiFuture[uint64_t](
semiFuture_getValueX5(val),
handle_uint64_t,
<PyObject *>fut
)
return fut
def get_value_x5_fibers(int val): def get_value_x5_fibers(int val):
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment