I wanted to get suggestions regarding the proper way of implementing callback functions in Cassandra.
I had made some APIs using Cassandra's C++ driver. Given below is how I'd used the callback function to execute my query(l_stmt is the prepared statement and rtInsertCallback is the callback function):
CassFuture * l_query_future = cass_session_execute(RtConnectionObj::ms_session, l_stmt);
CassError l_returnCode = cass_future_set_callback(l_query_future,rtInsertCallback,NULL);
if(l_returnCode != CASS_OK)
{
printf("\n [ %s::%d ] Error \n",__FILE__,__LINE__);
}
cass_future_free(l_query_future);
Assuming, the above code is executed in Thread 1, as per my current understanding, the callback function will be executed when the future is set and that too in a separate thread(Thread 2). The callback function is like this:
void rtInsertCallback(CassFuture* l_csp_future, void *data)
{
CassError l_returnCode = cass_future_error_code(l_csp_future);
if (l_returnCode != CASS_OK)
{
printf("\n[%s::%d] %s ",__FILE__,__LINE__,cass_error_desc(l_returnCode));
}
else
{
printf("\n [%s::%d] Data Inserted successfully ...",__FILE__,__LINE__);
}
}
I want to know, is it possible that, before the future is set or before the CassError l_returnCode = cass_future_error_code(l_csp_future); statement gets executed in Thread 2, the future gets freed by Thread 1 due to which the above statement in thread 2 will be operating on a freed future? If yes, then what should be the proper way of handling such scenario? If this question does not make any sense(due to my misunderstanding of any concept), please explain. Thanks!
You are free to release the future in "Thread 1" after the callback statement. Callback will have its own copy of the future to work upon.
The Cassandra callback function will also take care of resource cleanup after it gets processed. So we don't have to explicitly free the future.
Code Sample can be found here
https://github.com/datastax/cpp-driver/blob/master/examples/callbacks/callbacks.c
Related
I am developing a C++ app in which i need to receive messages from an MQ and then parsing them according to their type and for a particular reason I want to make this process (receiving a single message followed by processing it) asynchronous. Since, I want to keep things as simple as possible in a way that the next developer would have no problem continuing the code, I have written a very small class to implement Asynchrony.
I first raise a new thread and pass a function to the thread:
task = new thread([&] {
result = fn();
isCompleted = true;
});
task->detach();
and in order to await the task I do the following:
while (!isCompleted && !(*cancelationToken))
{
Sleep(5);
}
state = 1; // marking the task as completed
So far there is no problem and I have not faced any bug or error but I am not sure if this is "a good way to do this" and my question is focused on determining this.
Read about std::future and std::async.
If your task runs in another core or processor, the variable isCompleted may become un-synchronized having two copies in core cache. So you may be waiting more than needed.
If you have to wait for something it is better to use a semaphore.
As said in comments, using standard methods is better anyway.
I'm developing a Node.js application that incorporates a Windows DLL. The DLL manages scientific equipment, for context.
My interface from Node to the DLL is going well, however the DLL has some non-deterministic calls that depend on the network topology and RF signals in the room. These calls can take anywhere from 10 seconds to 10 minutes.
I'd like to get these calls off Node's event loop, and even avoid AsyncWorkers. I'd like to put them in their own C++ threads. I'm worried that I don't know enough Node/V8 to approach the problem correctly, though I've attempted twice now.
Below is my attempt at spawning a thread to call a js callback, though I'm not sure if this is a good approach. I need the result of the call, and what I have so far is a 'daemon' in my node app that checks on a regular interval to retrieve results for completed tasks.
mTp in the snippet below is a threadpool implementation I've written. Runtask takes a C++ lambda as a parameter to be pushed onto my worker thread queue. mThreadStatus is a map from my thread 'handle', which is a string, to thread_status_t enum. mThreadResults is another map from the thread handle to a v8::Value that gets returned by the callback.
void
MyObj::SpawnThread(functionInput info) {
MyObj* obj = ObjectWrap::Unwrap<MyObj>(info.Holder());
obj->mTp.RunTask([&]() {
v8::Isolate::CreateParams cp;
v8::Isolate* tpIsolate = v8::Isolate::New(cp);
v8::Locker locker(tpIsolate);
v8::Isolate::Scope isolateScope(tpIsolate);
Nan::HandleScope scope;
auto global = obj->mContext.Get(tpIsolate)->Global();
auto handle = std::string(*v8::String::Utf8Value(info[0]->ToString()));
{
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = thread_status_t::running;
}
v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(info[1]);
v8::TryCatch trycatch(tpIsolate);
v8::Handle<v8::Value> result = f->Call(global, 0, nullptr);
if (result.IsEmpty()) {
v8::Local<v8::Value> exception = trycatch.Exception();
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = thread_status_t::error;
return;
}
{
std::unique_lock<std::shared_mutex> resultLock(obj->mThreadResultsMutex);
obj->mThreadResults[handle] = result;
}
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = completed;
tpIsolate->Dispose();
});
I'm envisioning my js looking like this to spawn a thread:
var ctx = this
this.myObj.spawnThread('startMeasurements', () => {
return ctx.myObj.startMeasurements()
})
And like this to get the result, in my 'daemon':
var status = this.myObj.getThreadStatus('startMeasurements')
if ( status === 'complete') {
// Publish returned information to front-end
}
else if (status === 'error') {
// Handle error
}
Has anyone solved this problem before? Does this look like a decent approach? Help with v8 is greatly appreciated. Thank you!
I have not solved a similar problem before, but the general way I would go about it is:
let the JavaScript code be oblivious of the threading
expose a function getMeasurements(callback) to JavaScript, implemented in C++
when the function is called, it gets itself a thread (either newly created, or from the pool) and instructs it to do the blocking external call; when that call is completed the thread signals its result to the main thread, which invokes the callback with it.
that way all communication with JavaScript code (i.e. all interaction with V8) happens on the main thread, and you only use background threads for the blocking calls.
I hope this helps!
I am going to use WUA API and begin execution of an asynchronous search for updates in this way:
CComPtr<SearchCallbackImpl> iscc_; <<-- Note you need to CreateInstance
CComPtr<ISearchJob> pUpJob_;
pUpJob_ = NULL;
pUpSearcher_->BeginSearch(
CComVariant(criteria.c_str()).bstrVal,
iscc_,
CComVariant(L"Scanning"),
&pUpJob_);
When I need to stop my program, but ISearchJob has not completed yet, I use this code:
if (pUpJob_)
{
CComVariant isStopped;
pUpJob_->get_IsCompleted(&isStopped.boolVal);
if (isStopped.boolVal == VARIANT_FALSE)
{
if (SUCCEEDED(pUpJob_->RequestAbort()))
{
pUpJob_->CleanUp();
pUpJob_.Release();
}
}
}
Generally this code works but sometime it hangs on pUpJob_->CleanUp(); and I do not have ability to stop my programm correctly.
So my questions are:
What is the correct way to stop asynchronous search job for updates?
Also i misunderstood what is difference between ISearchJob::CleanUp and ISearchJob::RequestAbort and how to use this methods to stop asynchronous search correctly?
Should this methods be used together or separately?
RequestAbort() is also asynchronous (the hint to that is in the name). After calling it, you should call pUpSearcher_->EndSearch(); it will return an ISearchResult with ResultCode equal to orcAborted if the abort was successful. Then you can free your resources.
I'm not fully sure how CleanUp() is supposed to be used, but this page seems to imply it's intended for scripts that have callbacks, and that you're not supposed to call CleanUp() from within a callback. Not sure where your code for cancelling is run.
I need to call an Async method within a method I declared. The method should return a value. I'm trying to wrap calls to the Windows Store into an easy to use class. My method should look like this:
bool Purchase(enum_InAppOption optionToPurchase);
enum_InAppOption is an enum consisting of all In-App options to purchase. At some point I need to call RequestProductPurchaseAsync. The result of this call determines if the method should return trueor false. I'm new to c++/cx (or at least I have a long history between now and the last time I used c++), so maybe this is easier as I think.
The create_task looks like this:
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
The options I considered / tried:
returning the task would not abstract the store
tried to call wait on the task. I've got the exception An invalid parameter was passed to a function that considers invalid parameters fatal.
tried to use structured_task_group but it seems this does not allow for non void returning methods or I'm trying to provide a wrong interpretation. Compiler returns error C2064 (have googled but I can't get the point what to change)
Using an array of tasks and when_all
Found the following code on http://msdn.microsoft.com/en-us/library/dd492427.aspx#when_all in the middle of the page:
array<task<void>, 3> tasks =
{
create_task([] { wcout << L"Hello from taskA." << endl; }),
create_task([] { wcout << L"Hello from taskB." << endl; }),
create_task([] { wcout << L"Hello from taskC." << endl; })
};
auto joinTask = when_all(begin(tasks), end(tasks));
// Print a message from the joining thread.
wcout << L"Hello from the joining thread." << endl;
// Wait for the tasks to finish.
joinTask.wait();
So I tried to translate it into the following code:
array<task<Platform::String^>,1> tasks = {
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
};
Even though I included the compiler throws C2065 ('array': undeclared identifier), C2275 ('Concurrency::task<_ReturnType>': illegal use of this type as an expression and some errors that seem to be errors following up on those two.
To sum up: How to make the method return after the async task has completed, so I can return a meaningful result based on the stuff going on asynchronously?
How to make the method return after the async task has completed, so I can return a meaningful result based on the stuff going on asynchronously?
This doesn't make much sense: the "stuff" isn't asynchronous if you want to wait for it to complete before returning. That's the definition of synchronous.
When using C++/CX, you cannot wait on a not-yet-completed task on an STA. Any attempt to do so will result in an exception being thrown. If you are going to call Purchase() on an STA and if it starts an asynchronous operation, you cannot wait for that operation to complete before returning.
Instead, you can use .then to perform another operation when the asynchronous operation completes. If the continuation needs to be performed on the invoking thread, make sure to pass the use_current() continuation context to ensure that the continuation is executed in the correct context.
Sascha,
Returning a task would abstract out the store, and I think that would be the most reasonable decision, since you are not restricting the users of your helper class to get the results straight away, but also allowing them to handle the results in their own way and asynchronously.
As #James correctly mentioned, you are not allowed to wait in the UI thread, then you will make the app unresponsive, there are different ways to avoid waiting:
create a continuation with concurrency::task::then;
you cannot wait in the UI thread, but you can wait for an operation on the UI thread to complete, that means you can wrap the future result of the task running on UI in a task_completion_event and then wait on the event in another (background) thread and handle the result;
concurrency::task_completion_event<Platform::String^> purchaseCompleted;
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(
this->_LastProductId, false)).then(
[purchaseCompleted](concurrency::task<Platform::String^> task)
{
try
{
purchaseCompleted.set(task.get());
}
catch(Platform::Exception^ exception)
{
purchaseCompleted.set_exception(exception);
}
});
// and somewhere on non-UI thread you can do
Platform::String^ purchaseResult = create_task(purchaseCompleted).get();
you can achieve the previous trick using more WinRT-specific facilities rather than Concurrency Runtime, more precisely, IAsyncOperation<T>::Completed and IAsyncOperation<T>::GetResults;
and
seem irrelevant here, since you have only 1 real task, which is make a purchase.
I am writing a framework for an embedded device which has the ability to run multiple applications. When switching between apps how can I ensure that the state of my current application is cleaned up correctly? For example, say I am running through an intensive loop in one application and a request is made to run a second app while that loop has not yet finished. I cannot delete the object containing the loop until the loop has finished, yet I am unsure how to ensure the looping object is in a state ready to be deleted. Do I need some kind of polling mechanism or event callback which notifies me when it has completed?
Thanks.
Usually if you need to do this type of thing you'll have an OS/RTOS that can handle the multiple tasks (even if the OS is a simple homebrew type thing).
If you don't already have an RTOS, you may want to look into one (there are hundreds available) or look into incorporating something simple like protothreads: http://www.sics.se/~adam/pt/
So you have two threads: one running the kernel and one running the app? You will need to make a function in your kernel say ReadyToYield() that the application can call when it's happy for you to close it down. ReadyToYield() would flag the kernel thread to give it the good news and then sit and wait until the kernel thread decides what to do. It might look something like this:
volatile bool appWaitingOnKernel = false;
volatile bool continueWaitingForKernel;
On the app thread call:
void ReadyToYield(void)
{
continueWaitingForKernel = true;
appWaitingOnKernel = true;
while(continueWaitingForKernel == true);
}
On the kernel thread call:
void CheckForWaitingApp(void)
{
if(appWaitingOnKernel == true)
{
appWaitingOnKernel = false;
if(needToDeleteApp)
DeleteApp();
else
continueWaitingForKernel = false;
}
}
Obviously, the actual implementation here depends on the underlying O/S but this is the gist.
John.
(1) You need to write thread-safe code. This is not specific to embedded systems.
(2) You need to save state away when you do a context switch.