Discussion:
[asio-users] prioritizing and controlling the function execution in ASIO
Shiv Chawla
2011-10-24 14:42:39 UTC
Permalink
Hello

I was reading this post "strand-like priority queues"
http://comments.gmane.or/gmane.comp.lib.boost.asio.user/3531
and I found it very useful.

I am new to asio library and writing big program in c++. So I apologize if I am
not clear. I have a question related to prioritization.

Q1. How to get the execution status of a handler? If there are multiple
asynchronous functions and I need to dispatch one after the completion of
another, then how should I go about it? For ex:

void generateNumbers() //generates two numbers
{}

void swapNumbers() //Swap numbers..Swap has to wait for generate numbers
{}

I am working with an API with asynchronous functions where I send request to the
server and based on the result of request, I send another request. Now, deriving
from the above mentioned post, I can prioritize the function execution but I
need to know the status of first function. Is there any way with asio?

Thanks
Shiv
Gruenke, Matt
2011-10-24 16:59:18 UTC
Permalink
The straight-forward way to do this is by dispatching the second
function one from within the completion handler of the first. It helps
to think of this as a state machine. You can easily serialize the state
machine events & external actions upon it (such as cancelation) by using
a strand.

If you have lots of these running at any given time, they can share
strands. Just make sure that a given state machine always maps to the
same strand.


Matt


-----Original Message-----
From: Shiv Chawla [mailto:***@gmail.com]
Sent: Monday, October 24, 2011 10:43
To: asio-***@lists.sourceforge.net
Subject: [asio-users] prioritizing and controlling the function
execution inASIO

Hello

I was reading this post "strand-like priority queues"
http://comments.gmane.or/gmane.comp.lib.boost.asio.user/3531
and I found it very useful.

I am new to asio library and writing big program in c++. So I apologize
if I am
not clear. I have a question related to prioritization.

Q1. How to get the execution status of a handler? If there are multiple
asynchronous functions and I need to dispatch one after the completion
of
another, then how should I go about it? For ex:

void generateNumbers() //generates two numbers
{}

void swapNumbers() //Swap numbers..Swap has to wait for generate numbers
{}

I am working with an API with asynchronous functions where I send
request to the
server and based on the result of request, I send another request. Now,
deriving
from the above mentioned post, I can prioritize the function execution
but I
need to know the status of first function. Is there any way with asio?

Thanks
Shiv


------------------------------------------------------------------------
------
The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
Take a complimentary ***@Cisco Self-Assessment and learn
about Cisco certifications, training, and career opportunities.
http://p.sf.net/sfu/cisco-dev2dev
_______________________________________________
asio-users mailing list
asio-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Shiv Chawla
2011-10-24 18:58:41 UTC
Permalink
Post by Gruenke, Matt
The straight-forward way to do this is by dispatching the second
function one from within the completion handler of the first. It helps
to think of this as a state machine. You can easily serialize the state
machine events & external actions upon it (such as cancelation) by using
a strand.
If you have lots of these running at any given time, they can share
strands. Just make sure that a given state machine always maps to the
same strand.
Matt
-----Original Message-----
Sent: Monday, October 24, 2011 10:43
Subject: [asio-users] prioritizing and controlling the function
execution inASIO
Hello
I was reading this post "strand-like priority queues"
http://comments.gmane.or/gmane.comp.lib.boost.asio.user/3531
and I found it very useful.
I am new to asio library and writing big program in c++. So I apologize if I am
not clear. I have a question related to prioritization.
Q1. How to get the execution status of a handler? If there are multiple
asynchronous functions and I need to dispatch one after the completion of
void generateNumbers() //generates two numbers
{}
void swapNumbers() //Swap numbers..Swap has to wait for generate numbers
{}
I am working with an API with asynchronous functions where I send request to the
server and based on the result of request, I send another request. Now, deriving
from the above mentioned post, I can prioritize the function execution but I
need to know the status of first function. Is there any way with asio?
Thanks
Shiv
------------------------------------------------------------------------
------
The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
Take a complimentary Learning <at> Cisco Self-Assessment and learn
about Cisco certifications, training, and career opportunities.
http://p.sf.net/sfu/cisco-dev2dev
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
------------------------------------------------------------------------------
The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
Take a complimentary Learning <at> Cisco Self-Assessment and learn
about Cisco certifications, training, and career opportunities.
http://p.sf.net/sfu/cisco-dev2dev
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Thanks Matt

But this doesn't solve my problem or may be I don't understand it. Let me give
you an example of what I am doing.

I have an API which links to an external server. Every request to server is
followed by an ID. So if I want to compute function XYZ on the server, it is
accompanied by a ID. Now, before I send that request, I need to request an ID
(that's how the API works)

ReqID() //send request at the server
GetID(int& id) //callback function of ReqID()


Use_ID_in_XYZ(id, OtherArguments) //subsequent call to server for computing XYZ
{}

Now, I just cannot add subsequent functions in the callback. There is no one
method that I will call using ID but multiple of those.

Now , if you look at this.
http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/3578

It tells to keep a track of function in progress. I was thinking on similar
lines. I can prioritize my calls but I just don't understand how to keep a track
on the status of function in progress.

Thanks
Shiv
Marsh Ray
2011-10-24 19:16:15 UTC
Permalink
Post by Shiv Chawla
Post by Gruenke, Matt
The straight-forward way to do this is by dispatching the second
function one from within the completion handler of the first. It helps
to think of this as a state machine. You can easily serialize the state
machine events& external actions upon it (such as cancelation) by using
a strand.
I have an API which links to an external server. Every request to server is
followed by an ID. So if I want to compute function XYZ on the server, it is
accompanied by a ID. Now, before I send that request, I need to request an ID
(that's how the API works)
Now, I just cannot add subsequent functions in the callback. There is no one
method that I will call using ID but multiple of those.
Now , if you look at this.
http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/3578
It tells to keep a track of function in progress. I was thinking on similar
lines. I can prioritize my calls but I just don't understand how to keep a track
on the status of function in progress.
Store that "state" (i.e. which server function you are going to call
after you receive the ID) in an object. Arrange for the callback that
receives the ID to have access to that object.

It's that simple. I think you may be over-thinking this.

- Marsh
Marc Singer
2011-10-24 19:45:02 UTC
Permalink
Post by Shiv Chawla
Thanks Matt
But this doesn't solve my problem or may be I don't understand it. Let me give
you an example of what I am doing.
I have an API which links to an external server. Every request to server is
followed by an ID. So if I want to compute function XYZ on the server, it is
accompanied by a ID. Now, before I send that request, I need to request an ID
(that's how the API works)
ReqID() //send request at the server
GetID(int& id) //callback function of ReqID()
Use_ID_in_XYZ(id, OtherArguments) //subsequent call to server for computing XYZ
{}
Now, I just cannot add subsequent functions in the callback. There is no one
method that I will call using ID but multiple of those.
Now , if you look at this.
http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/3578
It tells to keep a track of function in progress. I was thinking on similar
lines. I can prioritize my calls but I just don't understand how to keep a track
on the status of function in progress.
Thanks
Shiv
What do you mean by "keeping track of status"? Do you need to be able to
query
where a given thread of execution is while un process? In other words, do
you need
to know if a particular request is in the 'request ID' phase vs. later
phases where it is used?

The boost::bind header is very helpful for passing state along with function
invocations
where callbacks are used to activate the user application. It may be
relevant in your situation unless you need to access that information
outside the thread
of execution. For example, if you associate this ID with a user's session
and need to reuse
it later when the user asks for more service. If instead the ID is just
local to a single
request then bind may be handy for tracking your state.

Cheers
Shiv Chawla
2011-10-25 14:29:22 UTC
Permalink
Well, I am new to a lot of things so I apologize for repetitive questions. Let
me explain you what I am trying to.

I have an API which has a certain defined functions and it's related callbacks.
All these functions are asynchronous in nature.

Now, using this API I want to construct an asynchronous system which sends
multiple request to the server for collecting different data items and then use
these data item for further use.

For example:

funtionA()
{
requestDataForA();
//wait for the callback asynchronously
//processDataForA();
}

funtionB()
{
requestDataForB();
//wait for the callback asynchronously
//processDataForB();
}

funtionC()
{
requestDataForC();
//wait for the callback asynchronously
//processDataForC();
}

Now, if all the functions A,B,C are running asynchronously, what would be an
ideal way to solve this problem? In one of the previous replies, someone
suggested to store the "state"(process to be called) and make that state
available to callback routines. Now, as there could be potentially multiple
request/process combinations, I don't really follow the solution.

If this is not a right portal for this question, please direct me to one.

Thanks
Shiv
Marsh Ray
2011-10-25 14:45:26 UTC
Permalink
Post by Shiv Chawla
funtionA()
{
requestDataForA();
//wait for the callback asynchronously
//processDataForA();
}
When you have a 'functionA()' that blocks its caller until the result is
available, that's an inherently synchronous API. There are patterns to
convert a synchronous design to an asynchronous one, but they add
significant complexity.

You're probably better off sticking with the synchronous design
presented by your API.

- Marsh
Shiv Chawla
2011-10-25 14:56:45 UTC
Permalink
Post by Marsh Ray
Post by Shiv Chawla
funtionA()
{
requestDataForA();
//wait for the callback asynchronously
//processDataForA();
}
When you have a 'functionA()' that blocks its caller until the result is
available, that's an inherently synchronous API. There are patterns to
convert a synchronous design to an asynchronous one, but they add
significant complexity.
You're probably better off sticking with the synchronous design
presented by your API.
- Marsh
Hey Marsh

API is asynchronous in nature. functionA() is my construct. API provides
requestDataForA()(asynchronous request) and getDataForA()(callback)

Shiv
Marsh Ray
2011-10-25 15:11:40 UTC
Permalink
API is asynchronous in nature. [...] API provides
requestDataForA()(asynchronous request) and getDataForA()(callback)
So then you don't need Boost.ASIO, which is the topic of this group.

- Marsh
Marc Singer
2011-10-25 17:10:40 UTC
Permalink
Post by Shiv Chawla
Well, I am new to a lot of things so I apologize for repetitive questions. Let
me explain you what I am trying to.
I have an API which has a certain defined functions and it's related callbacks.
All these functions are asynchronous in nature.
Now, using this API I want to construct an asynchronous system which sends
multiple request to the server for collecting different data items and then use
these data item for further use.
funtionA()
{
requestDataForA();
//wait for the callback asynchronously
//processDataForA();
}
funtionB()
{
requestDataForB();
//wait for the callback asynchronously
//processDataForB();
}
funtionC()
{
requestDataForC();
//wait for the callback asynchronously
//processDataForC();
}
Now, if all the functions A,B,C are running asynchronously, what would be an
ideal way to solve this problem? In one of the previous replies, someone
suggested to store the "state"(process to be called) and make that state
available to callback routines. Now, as there could be potentially multiple
request/process combinations, I don't really follow the solution.
If this is not a right portal for this question, please direct me to one.
Thanks
Shiv
There is a lot of good help offered by other writers on this list.
M. Ray may be correct in that your question isn't really about (or relevant
to) ASIO at all.

I wil offer a little more since I had a similar problem that was intertwined
with ASIO. And, to understand this problem completely you are probably
best served by *first* implementing a simple version of the system with
global state. I suggest this because a naive and working sample can help
you understand something more abstract as you develop it.

Your snippets above don't show the important piece which is the callback
and the method by which you wait for the result. Here is something I have
written. There is too much to paste in for a complete context so I'll
explain.

socket_.async_send (boost::asio::buffer (rgb, available),
boost::bind (&Session::handle_send,
shared_from_this (), t,
rgb, cbMax, offset,
available,
_1, _2)));

handle_send is the completion callback. I use bind to pass more than the
standard arguments that async_send() expects, e.g. const
boost::system::error_code& and std::size_t bytes_transferred. I'm passing
to a C++ object so there is a *this* pointer, a Thread object, a few
parameters used for buffer management, and then the standard arguments.

At the simplest level, you only need to understand that you can pass
arguments to an invocation of the callback that let you recover the state of
the caller. If we had closures we would not require the bind() trickery.
Though it isn't apparent in my example, you can use *shared_ptr* handles to
allocated objects and keep them alive as long as there is a pending or
active callback holding the pointer. IOW, if you pass a object *shared_ptr* to
a callback that object will remain valid while no executing function refers
to it. Constructing an object with reference counting would do the same
thing though I prefer *shared_ptr*.

The Thread object is a further optimization I use based on Protothreads. It
is common to use Continuous Passing Style suggested by M. Overminddl1. I
prefer the Protothread approach because it allows me to write a single
handler to concentrate the logic of the asynchronous operation. IMHO, the
collection of callbacks that arise from chaining together a state machine
tends to make code review difficult. There is a little more overhead with
Protothreads that some programmers may eschew. And I'm sure there are folks
who will swear that a chain of callbacks is perfectly easy to understand.
The Thread object contains either a simple scalar or a void* depending on
whether you use an ANSI compliant implementation or GCC extensions.

Cheers
Marsh Ray
2011-10-25 18:05:56 UTC
Permalink
There is a lot of good help offered by other writers on this list. M.
Ray may be correct in that your question isn't really about (or
relevant to) ASIO at all.
Note that I'm not trying to suggest that we should be unhelpful, but I
sincerely think we're leading Shiv down the wrong path. He has an
asynchronous API and he's trying to implement a blocking function on top
of it. In a sense, this is the exact opposite of what ASIO does.

Let's look at the problem again - as simple as possible.
funtionA()
{
requestDataForA(); //wait for the callback
asynchronously //processDataForA();
}
API provides
requestDataForA()(asynchronous request) and getDataForA()(callback)
Shiv needs to implement functionA() and the getDataForA() callback. He
needs a way to block the thread in functionA until the data arrives in
the callback on another thread.

He found an article about "prioritizing and controlling the function
execution in ASIO" but that's not what he needs.

Let's not overcomplicate it: What he needs is a collection of state
objects and a synchronization object for each thread to block on. This
is basic multithreaded programming, not something you would involve a
new IO framework library for.

- Marsh
Shiv Chawla
2011-10-26 19:42:58 UTC
Permalink
Post by Marsh Ray
He found an article about "prioritizing and controlling the function
execution in ASIO" but that's not what he needs.
Marsh, You must be cent percent right in your judgement as I am a novice and
don't even know what my problem is.

However, I will just reiterate my problem and may be you have a solution for it
or may be what you have already mentioned is what I need.

I have an API that comes with a lot of request functions and their
corresponding callbacks. For ex: requestA() has a callback
GetA(Result& resultA). Now all these functions are asynchronous in nature and I
don't know or understand what runs on which thread.

Now, My question is that if I make multiple request to the server for different
data items, all of these data items will get populated async in their callbacks.
I want a system which uses the result of multiple callbacks and does some
further processing.

functionXYZ()
{
requestA();
requestB();
requestC();
requestD();

//do something...let me give two use cases
requestE(arguments from results of above request);//async do something

printResults();//sync dosomething..prints the results of above request(ABCD)

}

Now, "do something" can be async or sync in nature. I have read a ton of
material but I don't see anything related or may be I don't have the eyes to
look for it.
Post by Marsh Ray
Let's not overcomplicate it: What he needs is a collection of state
objects and a synchronization object for each thread to block on. This
is basic multithreaded programming, not something you would involve a
new IO framework library for.
I don't understand this completely. If this is a solution to above mentioned
problem then could you please give a small example so that I can develop on that.

Thanks
Shiv
Marc Singer
2011-10-26 21:18:38 UTC
Permalink
Post by Shiv Chawla
Post by Marsh Ray
He found an article about "prioritizing and controlling the function
execution in ASIO" but that's not what he needs.
Marsh, You must be cent percent right in your judgement as I am a novice and
don't even know what my problem is.
IMHO, you may be pointing to the root issue. There are a several
ways one might tackle your problem, but we on this list don't
have enough information to answer you succinctly. Moreover, it
looks like you question is not really about ASIO.

In essence, you're asking for a tutorial on synchronization.
You'll be well served by doing some groundwork yourself. A good
place to start is with W Stevens,


http://www.amazon.com/W.-Richard-Stevens/e/B000AP9GV4/ref=ntt_athr_dp_pel_1.

If his writing is opaque to you, you may want to consider enrolling
in a programming class.

Cheers
Marsh Ray
2011-10-26 21:50:44 UTC
Permalink
Post by Marc Singer
In essence, you're asking for a tutorial on synchronization.
You'll be well served by doing some groundwork yourself. A good
place to start is with W Stevens,
http://www.amazon.com/W.-Richard-Stevens/e/B000AP9GV4/ref=ntt_athr_dp_pel_1.
Or how about
Robbins & Robbins
UNIX Systems Programming: Communication, Concurrency and Threads
http://www.amazon.com/dp/0130424110/

But keep in mind, as of today, doing multithreaded or asyncronous
programming usually involves some platform-specific coding. These books
are UNIX-oriented.
Post by Marc Singer
If his writing is opaque to you, you may want to consider enrolling
in a programming class.
+1. This stuff is hard. It's difficult to pick up on your own. There
aren't too many people who can even do it reliably.

This is what makes a good ASIO framework such a joy to use. But
frameworks are meant to form the core of the application and drive its
whole design from there. When, as in this case, they meet up with an
externally-imposed API with a different model it usually falls back to
programmer to implement the glue manually.

- Marsh
OvermindDL1
2011-10-25 15:02:23 UTC
Permalink
He means use Continuation Passing Style. On my phone so no pseudo-code, but
have your function accept a boost::function that returns void but accepts
what your function 'returns' while you actually return void. If you pass
nothing to the next function then do void. This lets you create a tree of
functions that call each other without needing to know anything about each
other. I use this pattern quite often, exceedingly useful to structure
actions in some patterns of code.
Post by Marc Singer
Post by Shiv Chawla
Thanks Matt
But this doesn't solve my problem or may be I don't understand it. Let me give
you an example of what I am doing.
I have an API which links to an external server. Every request to server is
followed by an ID. So if I want to compute function XYZ on the server, it is
accompanied by a ID. Now, before I send that request, I need to request an ID
(that's how the API works)
ReqID() //send request at the server
GetID(int& id) //callback function of ReqID()
Use_ID_in_XYZ(id, OtherArguments) //subsequent call to server for computing XYZ
{}
Now, I just cannot add subsequent functions in the callback. There is no one
method that I will call using ID but multiple of those.
Now , if you look at this.
http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/3578
It tells to keep a track of function in progress. I was thinking on similar
lines. I can prioritize my calls but I just don't understand how to keep a track
on the status of function in progress.
Thanks
Shiv
What do you mean by "keeping track of status"? Do you need to be able to
query
where a given thread of execution is while un process? In other words, do
you need
to know if a particular request is in the 'request ID' phase vs. later
phases where it is used?
The boost::bind header is very helpful for passing state along with
function invocations
where callbacks are used to activate the user application. It may be
relevant in your situation unless you need to access that information
outside the thread
of execution. For example, if you associate this ID with a user's session
and need to reuse
it later when the user asks for more service. If instead the ID is just
local to a single
request then bind may be handy for tracking your state.
Cheers
------------------------------------------------------------------------------
The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
about Cisco certifications, training, and career opportunities.
http://p.sf.net/sfu/cisco-dev2dev
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Rutger ter Borg
2011-10-25 14:51:52 UTC
Permalink
Post by Shiv Chawla
Hello
I was reading this post "strand-like priority queues"
http://comments.gmane.or/gmane.comp.lib.boost.asio.user/3531
and I found it very useful.
I am new to asio library and writing big program in c++. So I apologize if I am
not clear. I have a question related to prioritization.
Q1. How to get the execution status of a handler? If there are multiple
asynchronous functions and I need to dispatch one after the completion of
void generateNumbers() //generates two numbers
{}
void swapNumbers() //Swap numbers..Swap has to wait for generate numbers
{}
I am working with an API with asynchronous functions where I send request to the
server and based on the result of request, I send another request. Now, deriving
from the above mentioned post, I can prioritize the function execution but I
need to know the status of first function. Is there any way with asio?
Thanks
Shiv
Hello Shiv,

the main trick is to wrap your handler in another class and put some
extra info in it.

Your problem may be addressed with prioritising handlers, but that may
be an overkill. The way I am addressing your class of problems is by
tracking the execution count. Also see
http://www.terborg.net/reference_counter.zip

Possible use:

reference_counter gen_ctr( ios );
ios.post( gen_ctr.wrap( &generateNumbers ) );
ios.post( gen_ctr.wrap( &generateNumbers ) );
gen_ctr.async_wait( &swapNumbers );

Hth,

Cheers,

Rutger
Shiv Chawla
2011-10-27 16:06:00 UTC
Permalink
Post by Rutger ter Borg
the main trick is to wrap your handler in another class and put some
extra info in it.
Your problem may be addressed with prioritising handlers, but that may
be an overkill. The way I am addressing your class of problems is by
tracking the execution count. Also see
http://www.terborg.net/reference_counter.zip
reference_counter gen_ctr( ios );
ios.post( gen_ctr.wrap( &generateNumbers ) );
ios.post( gen_ctr.wrap( &generateNumbers ) );
gen_ctr.async_wait( &swapNumbers );
Thanks Rutger

This is a good start. This will definitely address my set of problems. However,
there is a small problem. I was thinking of extending this idea to multiple line
of execution. Is it possible to run multiple independent process using the same
io_service. I guess it is.

Now, if have to prioritize within these process then this reference counting
logic has to be extended for that scenario. Am I right and is it possible?

Thanks
Shiv
Marat Abrarov
2011-10-27 16:57:08 UTC
Permalink
Post by Shiv Chawla
Post by Rutger ter Borg
Your problem may be addressed with prioritising handlers, but that may
be an overkill. The way I am addressing your class of problems is by
tracking the execution count. Also see
http://www.terborg.net/reference_counter.zip
reference_counter gen_ctr( ios );
ios.post( gen_ctr.wrap( &generateNumbers ) );
ios.post( gen_ctr.wrap( &generateNumbers ) );
gen_ctr.async_wait( &swapNumbers );
Here's more generic solution:
http://blog.think-async.com/2008/10/asynchronous-forkjoin-using-asio.html
Post by Shiv Chawla
I was thinking of extending this idea to multiple line
of execution. Is it possible to run multiple independent process using the same
io_service. I guess it is.
Now, if have to prioritize within these process then this reference counting
logic has to be extended for that scenario. Am I right and is it possible?
Use http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/invocation/prioritised_handlers.cpp
or switch to Intel TBB.

Regards,
Marat Abrarov.

Loading...