stasher::client
->put_request
(): asynchronous version of put
()
put_request
() follows the naming convention
and usage described in the section called “Introduction”.
See
updatethread.C
for an example of using put_request
.
This example takes names of objects passed to updatethread
on the command line, and appends “Object #n
”
to the existing object, or creating it if it does not exist:
$ ./updatethread planets/mercury planets/venus planets/earth planets/mars planet
s/jupiter planets/saturn planets/uranus planets/neptune
Received update request for planets/mercury, checking its existing contents
Received update request for planets/venus, checking its existing contents
Received update request for planets/earth, checking its existing contents
Received update request for planets/mars, checking its existing contents
Received update request for planets/jupiter, checking its existing contents
Received update request for planets/saturn, checking its existing contents
Received update request for planets/uranus, checking its existing contents
Received update request for planets/neptune, checking its existing contents
Received existing contents of planets/mercury, updating it
Received existing contents of planets/venus, updating it
Received existing contents of planets/earth, updating it
Received existing contents of planets/mars, updating it
Received existing contents of planets/jupiter, updating it
Received existing contents of planets/saturn, updating it
Received existing contents of planets/uranus, updating it
Received existing contents of planets/neptune, updating it
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Use simpleget.C
or stasher to examine
the resulting contents of each object:
$ stasher
Ready, EOF to exit.
> connect
Connected to objrepo.example.com, node octopus.objrepo.example.com.
Maximum 10 objects, 32 Mb aggregate object size, per transaction.
Maximum 10 concurrent subscriptions.
octopus> get planets/earth
planets/earth:75CiNQlHVhTmAm0081NlJm00003Jo0m00318n4AS
Object #3
octopus> get planets/saturn
planets/saturn:ArCiNQlHVhTmAm0081NlJm00003Jo0m00318n4AS
Object #6
octopus>
Rerunning the same command appends a second line to each object, since it
already exists. This example implements a completely asycnhronous,
event and message-driven thread to handle updates. An instance of the
thread object gets created, and a thread gets started.
The first message to the thread gives it
a stasher::client
connection to
use. Afterwards, update
() takes an object name,
a functor, and a mcguffin for this request. The functor takes an
x::fdptr
and an x::uuid
for parameters. A non-null x::fdptr
contains
the contents of the existing object; or it's null
()
if the object does not exist (in which case the
x::uuid
is meaningless). The functor
returns a stasher::client::base::transaction
.
The update thread takes care of getting the existing object's contents,
and processing the transaction. The update thread takes multiple update
requests, and works on them asynchronously. It's not necessary to wait
for one update to be done, and for the update thread to release its
reference on the corresponding mcguffin, before sending the next one.
The above example specifies multiple objects on the command line.
updatethread.C
sends an update request for each
one of them, first, then waits for each one to get processed.
The above examples show the messages from
updatethread.C
that evidence its
asynchronous event and message-based design.
It's possible that sometimes their order might be slightly different, or
some of them might overlap each other. This is, of course, normal output
from an asynchronous, multithreaded application.
updatethread.C
also handles the
stasher::req_rejected_stat
error code from
put
()/put_request
().
This indicates that a conflicting update to the same object occured, at the
same time. This is handled by, essentially, restarting the update from
the start, retrieving the object's updated contents, and invoking
the functor again, to build another transaction.
Passing the same object name more than once is the best way to see this:
$ ./updatethread fruits/apple fruits/apple fruits/orange fruits/banana fruits/ap
ple
Received update request for fruits/apple, checking its existing contents
Received update request for fruits/apple, checking its existing contents
Received update request for fruits/orange, checking its existing contents
Received update request for fruits/banana, checking its existing contents
Received update request for fruits/apple, checking its existing contents
Received existing contents of fruits/apple, updating it
Received existing contents of fruits/apple, updating it
Received existing contents of fruits/orange, updating it
Received existing contents of fruits/banana, updating it
Received existing contents of fruits/apple, updating it
Transaction/request processed
Update of fruits/apple rejected because someone else updated it, trying again
Update of fruits/apple rejected because someone else updated it, trying again
Received existing contents of fruits/apple, updating it
Received existing contents of fruits/apple, updating it
Update of fruits/apple rejected because someone else updated it, trying again
Received existing contents of fruits/apple, updating it
Transaction/request processed
Transaction/request processed
Transaction/request processed
Transaction/request processed
Each object's update is independent of the other objects'.
The asynchronous update thread sends each update to the server, all based
on the previous contents of the object in question.
When more than one update name the same object, each update's previous
content is typically the same, and one of those updates get processed.
The other updates, of course, subsequently fail with
a stasher::req_rejected_stat
, and the update thread
handles it by taking it from the top.
Since each individual update appends
“Object #n
” to the existing
contents, the repeatedly-named objects get more than one of them:
$ stasher
Ready, EOF to exit.
> connect
Connected to objrepo.example.com, node octopus.objrepo.example.com.
Maximum 10 objects, 32 Mb aggregate object size, per transaction.
Maximum 10 concurrent subscriptions.
octopus> get fruits/apple
fruits/apple:rHbqdS4kqBKeAm000nJlJm00000nQWK00318n4AS
Object #1
Object #5
Object #2
octopus> get fruits/orange
fruits/orange:knbqdS4kqBKeAm000nJlJm00000nQWK00318n4AS
Object #3
octopus> get fruits/banana
fruits/banana:m1bqdS4kqBKeAm000nJlJm00000nQWK00318n4AS
Object #4
octopus>
The comments in
updatethread.C
explain the reason why they are out of order, in this example.