Merge Request #4 - October¶
Overview¶
This merge request adds strands and actors to make more optimized single threaded objects and reduce thread contention. It is recommended that services use the single-threaded mode.
Small Changes¶
PeriodicTask::start
now does nothing when called from within the callback- Added
qi::os::getEnvDefault
to easily get an environment variable and cast it - Fixed random deadlock on
Session::service
- Added Application argument
--qi-sdk-prefix
and environment variableQI_SDK_PREFIX
to specify where to find modules - Python: use sys.argv when no argument is provided to
Application
New feature: Strands and Actors¶
You can now create a single-threaded objects by inheriting from Actor, all calls will then be queued (instead of blocked by a mutex). Remote calls, future continuations, signal callbacks, periodic tasks callbacks and async calls are guaranteed to be single-threaded.
For in-process communications, this guarantees that signal callbacks will be triggered in order.
qi::Signal<int> sig;
sig.connect(&MyClass::myCallback, myObj);
sig(1);
sig(2);
// if MyClass is an actor, it is guaranteed that myCallback(1) will be called
// before myCallback(2)
Work is still in progress to support that for remote communications.
All this is also supported in Python if your object is single-threaded (the default), there is no need to inherit from anything.
It is recommended to write single-threaded services as thread contention is reduced by the framework in these cases. Furthermore, code do not need the use of synchronization primitives, which avoids a lot of bugs.
For further details, see qi::Actor and qi::Strand.
Deprecation: qi::async(Function, uint64_t)¶
The function qi::async(Function, uint64_t)
is now deprecated. Use the
alternatives which take a time point or a duration from qi clocks instead.
template<typename R>
Future<R> async(boost::function<R()> callback, qi::Duration delay);
template<typename R>
Future<R> async(boost::function<R()> callback, qi::SteadyClockTimePoint timepoint);
qi::async(&myFunction); // schedule immediately
qi::async(&myFunction, qi::MilliSeconds(100));
qi::async(&myFunction, qi::steadyClockNow() + qi::MilliSeconds(100));
You can now bind arguments directly when using qi::async
as you do when using
Future::connect
and others.
qi::async(&myFunction, 42, "test");