Skip to content

Commit

Permalink
Refactor async API
Browse files Browse the repository at this point in the history
  • Loading branch information
mnunberg committed Apr 24, 2013
1 parent 2a9a6e3 commit fdafb41
Show file tree
Hide file tree
Showing 10 changed files with 608 additions and 689 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -63,6 +63,7 @@ xs/plcb-util.h
xs/plcb-return.h
xs/plcb-convert.h
xs/plcb-commands.h
xs/plcb-multi.h
xs/typemap
xs/lcb_10_compat.h

Expand Down
5 changes: 5 additions & 0 deletions constants/idx_constants.pl
Expand Up @@ -105,6 +105,11 @@ BEGIN
ARITHMETIC
STATS
FLUSH
LOCK
UNLOCK
CAS
INCR
DECR
);
constant("PLCB_CMD_$_", name => "PLCBA_CMD_$_") for (@async_commands);

Expand Down
158 changes: 92 additions & 66 deletions lib/Couchbase/Client/Async.pm
Expand Up @@ -332,97 +332,123 @@ C data structure. RTFSC if you really wish to know what's inside there.
=head1 COUCHBASE COMMANDS AND RESULTS
This contains the higher level inteface for issuing commands, and asynchronously
awaiting for their results to trickle in.
The asynchronous interface to this is a bit ugly, and is intended to be wrapped
according to the style you prefer.
There is only one function with which to issue commands:
=head2 C<request>
Issue couchbase command(s).
$async->request(
PLCBA_CMD_*, REQTYPE_*,
sub {
my ($results,$arg) = @_;
print "i am a result callback.\n";
printf("I have results for these keys: %s\n",
join(",", keys %$results));
printf("My request argument was $arg\n");
},
"arg",
CBTYPE_*,
[....],
);
Pretty complicated, eh?
=head2 command($type, $cmdargs, $cbparams)
It was the only sane way to have a single request function without limiting the
featureset or duplicating code an insane amount of times.
Issue a command asynchronously.
The arguments are as follows:
The type is one of the C<PLCBA_CMD_*> constants:
=over
=item 0
=item PLCBA_CMD_GET
=item PLCBA_CMD_TOUCH
=item PLCBA_CMD_LOCK
=item PLCBA_CMD_REPLACE
The command. This is one of the C<PLCBA_CMD_*> macros, and are present in
L<Couchbase::Client::IDXConst>.
=item PLCBA_CMD_ADD
=item 1
=item PLCBA_CMD_APPEND
Request type. This is one of C<REQTYPE_SINGLE> or C<REQTYPE_MULTI>. If the former
is specified, then only one set of parameters for the command will be passed;
if the latter, then this will be a single command which will operate on a multitude
of keys.
=item PLCBA_CMD_PREPEND
=item 2
=item PLCBA_CMD_SET
Callback.
=item PLCBA_CMD_ARITHMETIC
This is the callback which will be invoked when the command receives results. It
is called with two arguments. The first argument is a hash reference with the
command key(s) as its keys, and L<Couchbase::Client::Return> objects as its
values, which contain information about the response and status of the command.
=item PLCBA_CMD_INCR
The second argument is a user defined 'arg' defined next.
=item PLCBA_CMD_DECR
=item 3
=item PLCBA_CMD_REMOVE
Argument
=item PLCBA_CMD_UNLOCK
This is a dummy argument passed to the callback, and can be whatever you want.
=back
The constants hopefully should be self-explanatory.
=item 4
The second parameter, the C<$cmdargs>, is an array reference of arguments to
pass to the commands. These follow the same semantics as in the C<*_multi>
variants (in fact, internally they mostly follow the same code path).
Callback type.
Finally, the C<$cbparams> parameter is a hashref containing the following keys:
=over
This is one of C<CBTYPE_COMPLETION> and C<CBTYPE_INCREMENTAL>.
=item C<callback>
In the case of the former, the callback will only be invoked once, when all
the results for all the keys have been gathered. In the case of the latter, the
callback will be invoked for each new result received.
Mandatory. A CODE reference or name of a function to be invoked when the
response arrives.
Note that the contents of the callback result hash is not automatically reset
in between calls, so it is advisable to clear the hash (or delete relevant keys)
if C<CBTYPE_INCREMENTAL> is used.
=item C<data>
=item 5
Optional. A scalar which is passed to the callback as its second argument
Command arguments.
=item C<type>
Either a L<Couchbase::Client::Async::Request> object, or an arrayref of such
objects; depending on whether C<REQTYPE_SINGLE> or C<REQTYPE_MULTI> was specifed,
respectively.
The type, or 'mode' of callback to use. Options are C<CBTYPE_INCREMENTAL>
and C<CBTYPE_COMPLETION>. The C<INCREMENTAL> type is useful if performing a
large get operation, where you wish to perform an action on each key as it arrives.
The L<Couchbase::Client::Async::Request> is a simple array, and it is not
strictly required to bless into this object. See its documentation for which
fields are provided, and which commands they apply to.
Otherwise, the default (C<CBTYPE_COMPLETION>) will only be invoked once the entire
set of commands have been completed.
It may help to use my L<Array::Assign> module to deal with the fields in the
array.
=back
The callback is always invoked with two arguments; the first is a hashref
of keys and L<Couchbase::Client::Return> object values; the second is the
C<data> parameter (if passed).
A callback may thus look like this
$async->command(PLCBA_CMD_GET, [ "key" ], {
data => "hello there",
callback => sub {
my ($results, $data) = @_;
my $single_result = $results->{key};
$single_result->value;
$single_result->is_ok; #etc..
print "$data\n"; # hello there
});
There are several convenience functions available as well:
=head2 get([$key], $cbparams)
=head2 get($key, $cbparams)
=head2 set($setparams, $cbparams)
=head2 add($addparams, $cbparams)
=head2 replace($replaceparams, $cbparams)
=head2 append($appendparams, $cbparams)
=head2 prepend($prependparams, $cbparams)
=head2 cas($casparams, $cbparams)
=head2 remove($rmparams, $cbparams)
=head2 get_multi(...)
=head2 set_multi(...)
=head2 add_multi(...)
=head2 replace_multi(...)
=head2 append_multi(...)
=head2 prepend_multi(...)
=head2 cas_multi(...)
=head2 remove_multi(...)

0 comments on commit fdafb41

Please sign in to comment.