On Thu, Oct 30, 2008 at 3:21 PM, Corin Langosch
<address@hidden> wrote:
Hi Raghavendra,
thank's for the explanations, I think I now got it :)
Here's a simple example of what I expect to happen, from a client-side
view:
fuse_request -> unify_lookup -> node1_lookup -> protocoll
-> network_send
-> node2_lookup -> protocoll
-> network_send
(this actually does nothing than setting up the stack and sending
the request to the server)
network_in -> protocoll -> stack_lookup_and_call_cbk ->
node2_lookup -> unify_lookup -> (no unwind, since we need two
responses/calls)
network_in -> protocoll -> stack_lookup_and_call_cbk ->
node1_lookup -> unify_lookup -> fuse_request
(order of node1 and node2 may vary, depeding on their reply
speed)
side note:
the individual stack_cbks itself only call unwind when they are fully
done, otherwise they'll stay on the stack and will so be called when
more data arrives.
So the most important thing is that all functions are 100%
non-blocking. Functions which can't avoid this (like those doing system
calls which block) must be implemented behind a thread-manager which
actually transfers blocking to non-blocking operations.
So everything looks quite good for me now. But looking at the
io-threads xlater puzzled me again a bit. Fox eample the iot_open
directly calls fops->open (so posix_open normally) which will block.
The iot_schedule is done in the iot_open_cbk, which is called when
posix_open finished it's work.
io-threads starts serializes all operations on an inode, when an open() is done on an inode. hence schedule() happens in {open,create}_cbk()
But what I'd expect iot_open to do is not to call the fops->open
directly but instead pass it to a worker thread of it's pool. This
thread will handle the fops->open and call iot_open_cbk (so passing
the data down the whole stack) when done. And this is correctly done in
all other fops like iot_close, iot_read...?
before the first open() call on an inode, there won't be a scheduled worker thread for any file.
Corin
Am 30.10.2008 05:09, Raghavendra G schrieb:
Hi Corin,
STACK_WIND and STACK_UNWIND are analogous to C procedure call and
return from it. But, the major difference is that in C when a return is
done from a procedure, the control is returned to the calling
procedure, but when a STACK_UNWIND is done, the control is returned to
the procedure provided as an argument to STACK_WIND macro (the "cbk"
argument). The STACK_WIND macro stores the "context" (call back
procedure etc) necessary to do this. A series of STACK_WIND macros
results in a stack of these contexts built on heap and the
corresponding STACK_UNWINDs results in unwinding of this stack (Note
that the stack built due to calls to STACK_WIND is different from the C
function stack, which is cleared as soon as the C function returns. But
the "context"/stack built by STACK_WIND is preserved across C
functions).
In other words, STACK_WIND/STACK_UNWIND implements continuations
(provided by lisp and other languages) for glusterfs in C.
These two macros are among the basic building blocks of glusterfs'
asynchronous model of operation.
STACK_WIND/STACK_UNWIND pair of macros helps to handle the operations
across the network (say between client and server) asynchronously. The
request/reply for/to an operation is written to network, but the
glusterfs is not blocked until the response is returned. Instead it
"pauses the current operation" and continues to act upon requests for
other operations. When the response is got, the corresponding "paused
operation" is resumed using the stack built by series of STACK_WINDs
till the request/reply was written to network.
regards,
On Thu, Oct 30, 2008 at 2:58 AM, Corin
Langosch
<address@hidden> wrote:
Hi,
I just looked some time at the code but I think I just didn't get the
usage of STACK_WIND / STACK_UNWIND right.
Looking at the macros and the translators (for example), STACK_WIND
simply seems to setup some datastructures and then call the suplied
function. After that function is done, the MACRO is done and code
executions continues normal.
So if I put a STACK_WIND into a loop (like in unify) the function passed
in the MACRO is simply called. So the calls don't happen in parallel but
normal seriazliezd, as they would have happened without using
STACK_WIND. So what is STACK_WIND all about - for me it currently seems
to be for passing (some common) data between function calls. It doesn't
execute any functions in parallel in order to reduce latencies caused by
the backends?
The function call in the STACK_UNWIND macro puzzles me even more. What
is this for? As the STACK_UNWIND function is called from within the
function called by STACK_WIND, I'd suspect some kind of loop?
What's about with the while(0) inside the macros. They don't do
anything? ;)
Thanks for any clarifications :)
Corin
_______________________________________________
Gluster-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/gluster-devel
--
Raghavendra G
_______________________________________________
Gluster-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/gluster-devel