I am developing an application with a realtime context.
One of the threads that executes in realtime context dequeues Task message objects from a mailbox (with real-time capabilities). Those Task messages contain a std::promise and a command.
After the thread gets the Task it executes the command and after that, std::promise::set_value() will be called.
Because of that, I am concerned that calling std::promise::set_value() might not have real-time capability.
Does anybody knows if set::value() internally allocates heap storage or does something else that would break the real-time capability?
Here is some snipplet to hopefully make my question clearer:
void RealTimeThread::exec()
{
while( active_ ) {
Task receivedTask;
if( mailbox_.getMailTimed( receivedTask, std::chrono::milliseconds( 100 ) ) ) {
try {
if( receivedTask.cmd ) {
receivedTask.cmd->execute();
} else {
// TODO: some internal actions on timeout
throw std::runtime_error{"Command invalid"};
}
// does the following call has real-time capabilities?
receivedTask.cmdPromise.set_value();
} catch( ... ) {
receivedTask.cmdPromise.set_exception( std::current_exception() );
}
}
}
}
If anybody is interested:
A std::promise can be constructed given a allocator. This is used to allocated the "shared state" which is used on the std::future objects.
If you can provide an allocator that allocated on realtime (deterministic) it is fine to use std::promise in such context.
Such an allocator is motley allocating from a memory block that was allocated before application entered realtime context.
Related
Hi guys i'm trying to improve performance of some computation in my system. Basically I want to generate a series of actions based on some data. This doesn't scale well and I want to try doing this in parallel and getting a result after (a bit like how futures work)
I have an interface with a series of implementations that get a collection of actions. And want to call all these in parallel and await the results at the end.
The issue is that, when I view the logs its clearly doing this sequentially and waiting on each action getter before going to the next one. I thought the async would do this asynchronously, but its not.
The method the runBlocking is in, is within a spring transaction. Maybe that has something to do with it.
runBlocking {
val actions = actionsReportGetters.map { actionReportGetter ->
async {
getActions(actionReportGetter, abstractUser)
}
}.awaitAll().flatten()
allActions.addAll(actions)
}
private suspend fun getActions(actionReportGetter: ActionReportGetter, traderUser: TraderUser): List<Action> {
return actionReportGetter.getActions(traderUser)
}
interface ActionReportGetter {
fun getActions(traderUser: TraderUser): List<Action>
}
Looks like you are doing some blocking operation in ActionReportGetter.getActions in a single threaded environment (probably in the main thread).
For such IO operations you should launch your coroutines in Dispatchers.IO which provides a thread pool with multiple threads.
Update your code to this:
async(Dispatchers.IO) { // Switch to IO dispatcher
getActions(actionReportGetter, abstractUser
}
Also getActions need not be a suspending function here. You can remove the suspend modifier from it.
Is there a way to hook into a Lambda's shutdown? I am opening a database connection and want to keep it open, but I want to make sure it gets closed when the Lambda is terminated.
You are probably interested in an event that is thrown when the Lambda instance is being killed and not when a single invocation ends, right? You have one option for both though, but I doubt that they'll help you..
You can either use the context method getRemainingTimeInMillis() (links to Node.js but similar in other programming languages) to find out when the current invocation of your Lambda function times out. This might be helpful to cleanup things or use the time of your Lambda function to the full extent. I don't recommend to cleanup your database connections at the end of each invocation because then you won't reuse them for future invocations which slows down your Lambda function. But if you're okay with that, then go for it. Remember that this only works as long as your function is running. As soon as you have returned a response, you can't perform any cleanup operations because your Lambda function will get into a 'sleep mode'. You need to do this before you return something.
Alternatively, you can make use of the Extensions API. It offers a shutdown phase and triggers an extension with a Shutdown event. However, since an extension sits besides your function (and not within your function code), I'm not sure if you have a chance to clean up any database connections with this approach... See also Lambda Execution Environment for additional information.
Assuming you have a pooled connection for a warm lambda, you may register a shutdown hook to close the DB connection or release any other resources, you only have 500 ms to perform this task.
class EnvironmentConfig {
private static volatile boolean shutdownRegistered;
private static volatile HikariDataSource ds;
private void registerShudownHook() {
if (!shutdownRegistered) {
synchronized (lock) {
if (!shutdownRegistered) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (ds != null) {
ds.close();
}
}));
EnvironmentConfig.shutdownRegistered = true;
}
}
}
}
public DataSource dataSource() throws PropertyVetoException {
HikariDataSource _ds = EnvironmentConfig.ds;
if (_ds == null) {
synchronized (lock) {
_ds = EnvironmentConfig.ds;
if (_ds == null) {
_ds = new HikariDataSource();
// TODO: set connection props
EnvironmentConfig.ds = _ds;
registerShudownHook();
}
}
}
return _ds;
}
}
You can reference the datasource anywhere to get a singleton copy which will create the instance and register the shutdown hook.
Your shutdown hook could do other tasks, provided it does them quickly, or you can register more than one hook, just don't go nuts with how many threads you're registering.
No, you can't hook into the shutdown of a Lambda Execution context.
Lambda handles that on it's own an decides if and when to re-use or destroy execution contexts.
You'll probably have to rely on the connections to time out on their own.
I have this sync modeled as a Single, and only 1 sync can be running at a time.
I'm trying to subscribe the "job" on a Schedulers.single() which mostly works, but inside the chain there are schedulers hops (to db writes scheduler), which unblocks the natural queue created by single()
Then I looked at flatMap(maxConcurrency=1) but this won't work, as that requires always the same instance. I.e. from what I understand, some sort of a Subject of sync requests, which however is uncomposable as my usecase mostly looks like this
fun someAction1AndSync(): Single<Unit> {
return someAction1()
.flatMap { sync() }
}
fun someAction2AndSync(): Single<Unit> {
return someAction2()
.flatMap { sync() }
}
...
as you can see, its separate sync Single instances :/
Also note someActionXAndSync should not emit until the sync is also done
Basically I'm looking for coroutines Semaphore
I can think of three ways:
use a single thread for whole sync operation (decoupling through queue)
use semaphore to protect sync method from entering multiple times (not recommended, because will block callee)
fast return, when sync is in progress (AtomicBoolean)
There might by other solutions, which I am not aware of.
fast return, when sync is in progress
Also note someActionXAndSync should not emit until the sync is also done
This solution will not queue up sync requests, but will fail fast. The callee must handle the error appropriately
SyncService
class SyncService {
val isSync: AtomicBoolean = AtomicBoolean(false)
fun sync(): Completable {
return if (isSync.compareAndSet(false, true)) {
Completable.fromCallable { "" }.doOnEvent { isSync.set(false) }
} else {
Completable.error(IllegalStateException("whatever"))
}
}
}
Handling
When sync process is already happening, you will receive an onError. This issue must be handled somehow, because the onError will be emitted to the subscriber. Either you are fine with it, or you could just ignore it with onErrorComplete
fun someAction1AndSync(): Completable {
return Single.just("")
.flatMapCompletable {
sync().onErrorComplete()
}
}
use a single thread for whole sync operation
You have to make sure, that the whole sync-process is processed in a single job. When the sync-process is composed of multiple reactive steps on other threads, it could happen, that another sync process is started, while one sync process is already in progress.
How?
You have to have a scheduler with one thread. Each sync invocation must be invoked from given scheduler. The sync operation must complete sync in one running job.
I would use this:
fun Observable<Unit>.forceOnlyOneSubscriber(): Observable<Unit> {
val subscriberCount = AtomicInteger(0)
return doOnSubscribe { subscriberCount.incrementAndGet() }
.doFinally { subscriberCount.decrementAndGet() }
.doOnSubscribe { check(subscriberCount.get() <= 1) }
}
You can always generify Unit using generics if you need.
Currently I am reading a lot about coroutines.
While I think I only partly understand what they do (Allowing a function to be returned and continued at a certain point for instance), I really don't know why I should use them. I see no real benefit in using a coroutine. For me these things look to me like goto with extra steps. Could someone give me a good real world example where a coroutine might really improve a code base? Maybe that helps me to get the concept.
Coroutines allow us to model cooperative multitasking systems in a very simple and modular way. This kind of systems may suit many problems like multi-agent games, stock market simulators, operating systems, etc.
The simplicity comes from the fact that we may need only two function-like coroutines to express the concept in code. Classes, state structures, function pointers are no longer required. Below is a pseudo-code illustration which defines a scheduler and a task. Unlike normal functions, both instances of task pass the execution to each other after do_one_step call.
void scheduler(list<task> tasks) {
while(true) {
for(t : tasks)
await t;
}
}
void task(int arg) {
while(1) {
do_one_step(arg);
yield;
}
}
void main() { await scheduler( list( { task(0), task(1) } ); }
More importantly, the code for task may now be modular: tasks are allowed to include subtasks, which resemble its structure. Any subtask may be designed as a valid task itself:
void subtask(int arg) {
do_one_step(arg);
yield;
do_one_step(arg);
yield;
}
void task(int arg) {
while(1) {
await subtask(arg);
yield;
}
}
void main() { await scheduler( list({task(0), task(1), subtask(2)}); }
Coroutines allow us to stack subtasks into larger tasks, and provide us with a new tool to modularize our solutions.
Here I have one service Called 'DataSaveService' which I used for Saving Objects like..
class DataSaveService {
static transactional = true
def saveObject(object)
{
if(object != null)
{
try
{
if(!object.save())
{
println( ' failed to save ! ')
System.err.println(object.errors)
return false
}
else
{
println('saved...')
return true
}
}
catch(Exception e)
{
System.err.println("Exception :" + e.getMessage())
return false
}
}
else
{
System.err.println("Object " + object + " is null...")
return false
}
}
}
this service is common, and used by many class`s object for storing.
when there is multiple request are there at that time is very slow for saving or you can say its bulky. Because of default scope i.e. singleton.
So, I think for reducing work, I am going to make this service as session scope. like..
static scope = 'session'
then after I am accessing this service and method in controller it generated exception..
what to do for session scope service?, any other idea for implementation this scenario......?
Main thing is I want need best performance in cloud. yeah, I need answer for cloud.
Singleton (if it's not marked as synchronized) can be called from different thread at same time, in parallel, w/o performance loss, it's not a bottleneck.
But if you really need thread safety (mean you have some shared state, that should be used inside one method call, or from different parts of application during one http request or even different requests from same user, and you aren't going to run your app in the cloud), then you can use different scopes, like session or request scope. But i'm not sure that it's a good architecture.
For your current example, there are no benefits of using non singleton scope. And also, you must be know that having few instances of same service requires extra mem and cpu resources.