-
Notifications
You must be signed in to change notification settings - Fork 7
/
ZooKeeper.pm
1318 lines (1017 loc) · 47.5 KB
/
ZooKeeper.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Net::ZooKeeper - Perl extension for Apache ZooKeeper
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use 5.008_008;
use strict;
use warnings;
package Net::ZooKeeper;
require Exporter;
require XSLoader;
our $VERSION = '0.41';
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'errors' => [qw(
ZOK
ZSYSTEMERROR
ZRUNTIMEINCONSISTENCY
ZDATAINCONSISTENCY
ZCONNECTIONLOSS
ZMARSHALLINGERROR
ZUNIMPLEMENTED
ZOPERATIONTIMEOUT
ZBADARGUMENTS
ZINVALIDSTATE
ZAPIERROR
ZNONODE
ZNOAUTH
ZBADVERSION
ZNOCHILDRENFOREPHEMERALS
ZNODEEXISTS
ZNOTEMPTY
ZSESSIONEXPIRED
ZINVALIDCALLBACK
ZINVALIDACL
ZAUTHFAILED
ZCLOSING
ZNOTHING
ZSESSIONMOVED
)],
'node_flags' => [qw(
ZOO_EPHEMERAL
ZOO_SEQUENCE
)],
'acl_perms' => [qw(
ZOO_PERM_READ
ZOO_PERM_WRITE
ZOO_PERM_CREATE
ZOO_PERM_DELETE
ZOO_PERM_ADMIN
ZOO_PERM_ALL
)],
'acls' => [qw(
ZOO_OPEN_ACL_UNSAFE
ZOO_READ_ACL_UNSAFE
ZOO_CREATOR_ALL_ACL
)],
'events' => [qw(
ZOO_CREATED_EVENT
ZOO_DELETED_EVENT
ZOO_CHANGED_EVENT
ZOO_CHILD_EVENT
ZOO_SESSION_EVENT
ZOO_NOTWATCHING_EVENT
)],
'states' => [qw(
ZOO_EXPIRED_SESSION_STATE
ZOO_AUTH_FAILED_STATE
ZOO_CONNECTING_STATE
ZOO_ASSOCIATING_STATE
ZOO_CONNECTED_STATE
)],
'log_levels' => [qw(
ZOO_LOG_LEVEL_OFF
ZOO_LOG_LEVEL_ERROR
ZOO_LOG_LEVEL_WARN
ZOO_LOG_LEVEL_INFO
ZOO_LOG_LEVEL_DEBUG
)]
);
{
my %tags;
push @{$EXPORT_TAGS{'all'}},
grep {!$tags{$_}++} @{$EXPORT_TAGS{$_}} foreach (keys(%EXPORT_TAGS));
push @{$EXPORT_TAGS{'all'}}, qw(
ZOO_VERSION
);
}
# Provide human readable-ish error messages until the C API has strerr() built-in
my %ERRORS = (
-1 => "ZSYSTEMERROR",
-2 => "ZRUNTIMEINCONSISTENCY",
-3 => "ZDATAINCONSISTENCY",
-4 => "ZCONNECTIONLOSS",
-5 => "ZMARSHALLINGERROR",
-6 => "ZUNIMPLEMENTED",
-7 => "ZOPERATIONTIMEOUT",
-8 => "ZBADARGUMENTS",
-9 => "ZINVALIDSTATE",
+
-100 => "ZAPIERROR",
-101 => "ZNONODE",
-102 => "ZNOAUTH",
-103 => "ZBADVERSION",
-108 => "ZNOCHILDRENFOREPHEMERALS",
-110 => "ZNODEEXISTS",
-111 => "ZNOTEMPTY",
-112 => "ZSESSIONEXPIRED",
-113 => "ZINVALIDCALLBACK",
-114 => "ZINVALIDACL",
-115 => "ZAUTHFAILED",
-116 => "ZCLOSING",
-117 => "ZNOTHING",
-118 => "ZSESSIONMOVED",
);
sub str_error
{
my ($self) = @_;
return exists $ERRORS{$self->get_error} ? $ERRORS{$self->get_error} : "Unknown error";
}
our @EXPORT_OK = ( @{$EXPORT_TAGS{'all'}} );
XSLoader::load('Net::ZooKeeper', $VERSION);
1;
__END__
=head1 NAME
Net::ZooKeeper - Perl extension for Apache ZooKeeper
=head1 SYNOPSIS
use Net::ZooKeeper qw(:node_flags :acls);
my $zkh = Net::ZooKeeper->new('localhost:7000');
$zkh->create('/foo', 'bar',
'flags' => ZOO_EPHEMERAL,
'acl' => ZOO_OPEN_ACL_UNSAFE) or
die("unable to create node /foo: " . $zkh->get_error() . "\n");
print "node /foo has value: " . $zkh->get('/foo') . "\n";
$zkh->set('/foo', 'baz');
print "node / has child nodes:\n";
foreach my $path ($zkh->get_children('/')) {
print " /$path\n";
}
my $stat = $zkh->stat();
if ($zkh->exists('/foo', 'stat' => $stat)) {
print "node /foo has stat info:\n";
while (my($key,$value) = each(%{$stat})) {
print " $key: $value\n";
}
}
foreach my $acl_entry ($zkh->get_acl('/foo')) {
print "node /foo has ACL entry:\n";
print " perms: $acl_entry->{perms}\n";
print " scheme: $acl_entry->{scheme}\n";
print " id: $acl_entry->{id}\n";
}
my $watch = $zkh->watch('timeout' => 10000);
$zkh->exists('/foo', 'watch' => $watch);
if ($watch->wait()) {
print "watch triggered on node /foo:\n";
print " event: $watch->{event}\n";
print " state: $watch->{state}\n";
}
else {
print "watch timed out after 10 seconds\n";
}
$zkh->delete('/foo');
=head1 DESCRIPTION
Net::ZooKeeper provides a Perl interface to the synchronous C API
of Apache ZooKeeper. ZooKeeper is coordination service for
distributed applications.
Each connection to ZooKeeper is represented as a handle object
of the class Net::ZooKeeper, similar to the manner in which database
connections are represented in the DBI module.
To disconnect from ZooKeeper, simply destroy the Net::ZooKeeper
handle object by undefining it or by explicitly calling the
C<DESTROY()> method.
The methods which may be invoked on Net::ZooKeeper handles
correspond to the functions of the synchronous ZooKeeper C API;
e.g., the Net::ZooKeeper method C<create()> calls the ZooKeeper
C function C<zoo_create()>, C<delete()> calls C<zoo_delete()>,
and so forth.
The synchronous API functions wait for a response from the ZooKeeper
cluster before returning a result to the caller. Using these
functions permits Net::ZooKeeper to provide an interface similar
to that of a DBI driver module.
=head2 Internal POSIX Threads
The use of the synchronous ZooKeeper C API still requires that
the ZooKeeper C client code create several POSIX threads which run
concurrently with the main thread containing the Perl interpreter.
The synchronous API functions are wrappers of the asynchronous
functions in the ZooKeeper C API. When a request is made by the
caller's thread (i.e., the one with the running Perl interpreter),
it is enqueued for delivery at a later time by the ZooKeeper C client
code's IO thread. The caller's thread then waits for notification
before returning from the synchronous API function.
The IO thread dequeues the request and sends it to the ZooKeeper
cluster, while also ensuring that a regular "heartbeat" is maintained
with the cluster so that the current session does not time out.
When the IO thread receives a response from
the ZooKeeper cluster, it enqueues the response for delivery to the
client by the second thread of the ZooKeeper client code, the
completion thread.
If the caller is using the asynchronous API, the completion thread
invokes the appropriate callback function provided by the caller
for the given request. In the case of Net::ZooKeeper, it is not
viable for the completion thread to invoke a Perl callback function
at arbitrary times; this could interfere with the state of the
Perl interpreter.
For this reason Net::ZooKeeper uses the synchronous API only. After
enqueuing requests the synchronous API functions wait for notification
of the corresponding response. The completion thread delivers these
notifications, at which point the synchronous functions return to
their caller.
Note that the IO and completion threads are POSIX threads, not
Perl ithreads. Net::ZooKeeper defined a C<CLONE_SKIP()> function so
that if Perl ithreads are spawned while a Net::ZooKeeper connection
is active, the Net::ZooKeeper handle objects inherited by the
spawned ithread contain undefined values so that they can not be used.
Thus each ithread will need to create its own private connections to a
ZooKeeper cluster.
Note also that before invoking C<fork()> to spawn a new process,
all Net::ZooKeeper handles should be destroyed so that all
connections to ZooKeeper are closed and all internal POSIX threads
have exited. If a child process needs to communicate with
ZooKeeper it should open its own private connections after it is
created by C<fork()>.
=head2 Signals
The ZooKeeper C API uses TCP connections to communicate with
the ZooKeeper cluster. In older ZooKeeper versions(before 3.4.0), these connections may generate SIGPIPE
signals when they encounter errors, such as when a connection
is terminated by a ZooKeeper server. Therefore applications using older ZooKeeper versions
will want to trap or ignore SIGPIPE signals, e.g.:
local $SIG{'PIPE'} = 'IGNORE';
Ignoring SIGPIPE signals (or providing a signal handler that returns
control to the interrupted program after receiving the signal)
will allow the ZooKeeper C client code to detect the connection error
and report it upon return from the next Net::ZooKeeper method.
=head2 Error Handling
Net::ZooKeeper methods return different values in the case of an
error depending on their purpose and context. For example,
C<exists()> returns true if the node exists and false otherwise,
which may indicate either that the node does not exist or that
an error occurred.
After any method returns a false, empty, or undefined value which
might indicate an error has occurred, the C<get_error()> method
may be called to examine the specific error code, if any.
If C<get_error()> returns C<ZOK>, no error has occurred. If the
error code is less than C<ZAPIERROR>, it indicates a normal error
condition reported by the ZooKeeper server, such as C<ZNONODE>
(node does not exist) or C<ZNODEEXISTS> (node already exists).
If the error code is greater than C<ZAPIERROR>, then a connection
error or server error has occurred and the client should probably
close the connection by undefining the Net::ZooKeeper handle object
and, if necessary, attempt to create a new connection to the
ZooKeeper cluster.
In order to get a human-readable version of the error code,
simply call C<str_error()>, and it will return a string representing
the last encountered error.
=head2 Access Control
If the ZooKeeper cluster is not configured with C<skipACL=yes> then
it will respect the access controls set for each node in the
ZooKeeper hierarchy. These access controls are defined using ACLs
(Access Control Lists); see the ZooKeeper documentation for compete
details.
In Net::ZooKeeper, ACLs are represented as arrays of hashes, where
each hash is an ACL entry that must contain three attributes,
C<perms>, C<scheme>, and C<id>. The C<perms> attribute's value
should be composed by combining ACL permission flags using the
bitwise OR operator. See C<:acl_perms> for a list of the
available ACL permission flags.
The ACL for a node may be read using the C<get_acl()> method. A
node's ACL may be set when the node is created by passing an ACL
array as the value of the C<'acl'> option to the C<create()> method,
and may be updated by passing an ACL array to the C<set_acl()> method.
When a client connects to a ZooKeeper cluster it is automatically
assigned authentication credentials based on its IP address.
Additional authentication credentials may be added using
the C<add_auth()> method. Once a credential has been added for
the current session, there is no way to disable it.
As an example, digest authentication may be enabled for a session
by calling C<add_auth()> as follows:
$zkh->add_auth('digest', "$username:$password");
Note that the username and password are transmitted in cleartext
to the ZooKeeper cluster.
Such authentication credentials would enable access to a node
whose ACL contained an entry with a C<scheme> attribute of
C<'digest'> and an C<id> attribute containing a Base64-encoded
SHA1 digest of the string C<"$username:$password">. The
Perl modules Digest and MIME::Base64 may be used to create
such ACL ID values as follows:
use Digest qw();
use MIME::Base64 qw();
my $ctx = Digest->new('SHA-1')->add("$username:$password");
my $digest = MIME::Base64::encode($ctx->digest());
Note that using the C<b64digest()> method of the Digest module
will not result in digest strings with the "=" suffix characters
required by ZooKeeper.
=head2 Logging
As of ZooKeeper version 3.2.0, logging in the C client code is
implemented with a single, shared file handle to which all
of the internal POSIX threads write log messages; by default,
this file handle is attached to STDERR.
Moreover, this file handle is shared by all active ZooKeeper
connections (each of which has its own private IO and completion
threads; see L</Internal POSIX Threads> above).
Net::ZooKeeper therefore does not provide per-connection handle
attributes related to logging. The global function
C<Net::ZooKeeper::set_log_level()> may be used to set the current
log level. See C<:log_levels> for a list of the available log
levels. The default log level is C<ZOO_LOG_LEVEL_OFF>.
To capture ZooKeeper log messages to a file instead of STDERR,
redirect STDERR to a new file handle in the normal Perl manner:
open(OLDERR, '>&', fileno(STDERR)) or
die("unable to dup STDERR: $!");
open(STDERR, '>', $log_file) or
die("unable to redirect STDERR: $!");
=head2 Connection Order
ZooKeeper clusters are typically made up of an odd number of
ZooKeeper servers. When connecting to such a cluster, the
C<new()> method should be passed a comma-separated list of
the hostnames and ports for each of the servers in the cluster,
e.g., C<'host1:7000,host2:7000,host2:7100'>.
The default behaviour of the ZooKeeper client code is to
reorder this list randomly before making any connections.
A connection is then made to the first server in the reordered
list. If that connection fails, the IO thread will
automatically attempt to reconnect to the cluster, this time
to the next server in the list; when the last server in the list
is reached, the IO thread will continue again with the first
server.
For certain purposes it may be necessary for ZooKeeper clients
to know the exact order in which the IO thread will attempt to
connect to the servers of a cluster. To do so, call
C<Net::ZooKeeper::set_deterministic_conn_order(1)>. Note,
however, that this will affect all Net::ZooKeeper object
handles created by the current process.
=head1 ATTRIBUTES
=head2 Net::ZooKeeper
The Net::ZooKeeper class provides the main interface to the
ZooKeeper client API. The following attributes are available
for each Net::ZooKeeper handle object and are specific to
that handle and the method calls invoked on it. As with DBI
handle objects, attributes may be read and written through
a hash interface, e.g.:
print sprintf("Session timeout is %.2f seconds.\n",
$zkh->{session_timeout} / 1000);
$zkh->{watch_timeout} = 10000;
=over 4
=item hosts
The comma-separated list of ZooKeeper server hostnames and ports
as passed to the C<new()> method. Note that by default the
ZooKeeper C client code will reorder this list before attempting
to connect for the first time; see L</Connection Order> for details.
This attribute is B<read-only> and may not be modified.
=item session_timeout
The session timeout value, in milliseconds, as set by the
ZooKeeper server after connection. This value may not be
exactly the same as what was requested in the C<'session_timeout'>
option of the C<new()> method; the server will adjust the
requested timeout value so that it is within a certain range
of the server's C<tickTime> setting. See the ZooKeeper
documentation for details.
Because the actual connection to the ZooKeeper server is
not made during the C<new()> method call but shortly
thereafter by the IO thread, note that this value may not
be initialized to its final value until at least one
other method which requires communication with the server
(such as C<exists()>) has succeeded.
This attribute is B<read-only> and may not be modified.
=item session_id
The client's session ID value as set by the ZooKeeper server
after connection. This is a binary data string which may
be passed to subsequent C<new()> calls as the value of
the C<'session_id'> option, if the user wishes to attempt to
continue a session after a failure. Note that the server
may not honour such an attempt.
Because the actual connection to the ZooKeeper server is
not made during the C<new()> method call but shortly
thereafter by the IO thread, note that this value may not
be initialized to its final value until at least one
other method which requires communication with the server
(such as C<exists()>) has succeeded.
This attribute is B<read-only> and may not be modified.
=item data_read_len
The maximum length of node data that will be returned to
the caller by the C<get()> method. If a node's data exceeds
this length, the returned value will be shorter than the
actual node data as stored in the ZooKeeper cluster.
The default maximum length of the node data returned by
C<get()> is 1023 bytes. This may be changed by setting
the C<data_read_len> attribute to a different value.
Passing a value for the C<'data_read_len'> option when calling
the C<get()> method will temporarily override the per-handle
maximum.
=item path_read_len
The maximum length of a newly created node's path that will
be returned to the caller by the C<create()> method. If the path
of the newly created node exceeds this length, the returned
value will be shorter than the actual path of the node as stored
in the ZooKeeper cluster.
The default maximum length of the node path returned by
C<create()> is 1023 bytes. This may be changed by setting
the C<path_read_len> attribute to a different value.
Passing a value for the C<'path_read_len'> option when calling
the C<create()> method will temporarily override the current
value of this attribute.
=item watch_timeout
The C<timeout> attribute value, in milliseconds, inherited by
all watch objects (of class Net::ZooKeeper::Watch) created by
calls to the C<watch()> method. When a watch object's
C<wait()> method is invoked without a C<'timeout'> option,
it waits for an event notification from the ZooKeeper cluster
for no longer than the timeout period specified by the value of
the watch object's C<timeout> attribute.
The default C<timeout> attribute value for all watch objects
created by the C<watch()> method is 1 minute (60000
milliseconds). This may be changed for a particular handle
object by setting this attribute to a different value; afterwards,
the new value will be inherited by any watch objects created
by the handle object's C<watch()> method. Previously
created watch objects will not be affected.
Passing a value for the C<'timeout'> option when calling
the C<watch()> method will temporarily override the current
value of this attribute and cause the newly created watch object
to inherit a different value.
See also the C<watch()> method, and the C<timeout> attribute
and C<wait()> method of the Net::ZooKeeper::Watch class.
=item pending_watches
The number of internal ZooKeeper watches created for this handle
object that are still awaiting an event notification from the
ZooKeeper cluster.
Note that this number may be different than the number of
extant watch objects created by the handle object's C<watch()>
method, not only because some event notifications may have
occurred, but also if any watch objects have been reassigned
by reusing them in more than one call to any of the C<exists()>,
C<get_children()>, or C<get()> methods.
This attribute is B<read-only> and may not be modified.
=item state
The state of the Net::ZooKeeper connection at current time.
See C<:states> for a list of the possible connection states.
If zero, no connection has established yet.
This attribute is B<read-only> and may not be modified.
=back
=head2 Net::ZooKeeper::Stat
The Net::ZooKeeper::Stat class provides a hash interface to
the individual pieces of information which together compose the
state of a given ZooKeeper node. Net::ZooKeeper::Stat objects
are created by calling the C<stat()> method on a Net::ZooKeeper
handle object, and may then be passed to any methods which accept
a C<'stat'> option value, such as C<exists()>.
Net::ZooKeeper::Stat objects may be reused multiple times.
If the Net::ZooKeeper method to which the stat object is
passed succeeds, then the stat object is updated with the newly
retrieved node state information, and any state information
previously stored in the stat object is overwritten.
All of the attributes of stat objects are B<read-only>.
=over 4
=item ctime
The creation time of the node in milliseconds since the epoch.
=item mtime
The time of the last modification of the node's data in
milliseconds since the epoch.
=item data_len
The length of the node's data in bytes.
=item num_children
The number of child nodes beneath of the current node.
=item ephemeral_owner
If the node was created with the C<ZOO_EPHEMERAL> flag,
this attribute holds the session ID of the ZooKeeper client
which created the node. If the node was not created with
the C<ZOO_EPHEMERAL> flag, this attribute is set to zero.
=item version
The number of revisions of the node's data. The ZooKeeper
cluster will increment this version number whenever the
node's data is changed. When the node is first created this
version number is initialized to zero.
=item acl_version
The number of revisions of the node's ACL. The ZooKeeper
cluster will increment this version number whenever the
node's ACL is changed. When the node is first created this
version number is initialized to zero.
=item children_version
The number of revisions of the node's list of child nodes.
The ZooKeeper cluster will increment this version number
whenever the list of child nodes is changed. When the node
is first created this version number is initialized to zero.
=item czxid
The ZooKeeper transaction ID (ZXID) of the transaction which
created the node.
=item mzxid
The ZooKeeper transaction ID (ZXID) of the transaction which
last modified the node's data. This is initially set to
the same transaction ID as the C<czxid> attribute by the
C<create()> method.
=item children_zxid
The ZooKeeper transaction ID (ZXID) of the transaction which
last modified the node's list of child nodes. This is
initially set to the same transaction ID as the C<czxid>
attribute by the C<create()> method.
=back
=head2 Net::ZooKeeper::Watch
The Net::ZooKeeper::Watch class provides a hash interface
to the data returned by event notifications from the ZooKeeper
cluster. Net::ZooKeeper::Watch objects are created by calling
the C<watch()> method on a Net::ZooKeeper handle object, and
may then be passed to any methods which accept a C<'watch'>
option value, such as C<exists()>.
Net::ZooKeeper::Watch objects may be reused multiple times.
Regardless of whether the Net::ZooKeeper method to which the
watch object is passed succeeds, the watch object will be
updated to receive an event notification exclusively for the
node referenced in that method call. In the case of an error,
however, the watch object may never receive any event
notification.
=over 4
=item timeout
The default timeout value, in milliseconds, for all
invocations of the C<wait()> method made on the watch object.
When the C<wait()> method is invoked without a
C<'timeout'> option value, it waits for an
event notification from the ZooKeeper cluster for no longer
than the timeout period specified by this attribute.
This default timeout period may be altered by setting this
attribute to a different value.
Passing a value for the C<'timeout'> option when calling
the C<wait()> method will temporarily override the current
value of this attribute and cause the C<wait()> method to
use a different timeout period.
When a Net::ZooKeeper handle object's C<watch()> method is
invoked without a C<'timeout'> option, it returns a newly
created watch object whose C<timeout> attribute value
is initialized to the current value of the handle object's
C<watch_timeout> attribute. When the C<watch()> method is invoked
with a C<'timeout'> option, the new watch object's C<timeout>
attribute value is initialized to the value specified by
the C<'timeout'> option.
See also the C<wait()> method, and the C<watch_timeout> attribute
and C<watch()> method of the Net::ZooKeeper class.
=item event
The type of event which triggered the notification, such
as C<ZOO_CHANGED_EVENT> if the node's data was changed.
See C<:events> for a list of the possible event types.
If zero, no event notification has occurred yet.
Note that the events which will trigger a notification
will depend on the Net::ZooKeeper method to which
the watch object was passed. Watches set through the
C<exists()> and C<get()> methods will report events relating
to the node's data, while watches set through the
C<get_children()> method will report events relating to the
creation or deletion of child nodes of the watched node.
This attribute is B<read-only> and may not be modified.
=item state
The state of the Net::ZooKeeper connection at the time of
the event notification. See C<:states> for a list of
the possible connection states. If zero, no event
notification has occurred yet.
This attribute is B<read-only> and may not be modified.
=back
=head1 METHODS
=head2 Net::ZooKeeper
The following methods are defined for the Net::ZooKeeper class.
=over 4
=item new()
$zkh = Net::ZooKeeper->new('host1:7000,host2:7000');
$zkh = Net::ZooKeeper->new('host1:7000,host2:7000',
'session_timeout' => $session_timeout,
'session_id' => $session_id);
Creates a new Net::ZooKeeper handle object and attempts to
connect to the one of the servers of the given ZooKeeper
cluster. On failure, undef will be returned and the error message will be accessible in "$!". As described in the L</Internal POSIX Threads> and
L</Connection Order> sections, the ZooKeeper client code will
create an IO thread which maintains the connection with a
regular "heartbeat" request. In the event of a connection error
the IO thread will also attempt to reconnect to another one of
the servers using the same session ID. In general, these actions
should be invisible to the user, although Net::ZooKeeper methods
may return transient errors while the IO thread
reconnects with another server.
To disconnect, undefine the Net::ZooKeeper handle object
or call the C<DESTROY()> method. (After calling C<DESTROY()>
the handle object can not be reused.)
The ZooKeeper client code will send a "heartbeat" message
if a third of the session timeout period has elapsed without
any communication with the ZooKeeper server. A specific
session timeout period may be requested when creating a
Net::ZooKeeper handle object by supplying a value, in
milliseconds, for the C<'session_timeout'> option. The
ZooKeeper server adjust the requested timeout value so that
it is within a certain range of the server's C<tickTime> setting;
the actual session timeout value will be available as the
value of the handle's C<session_timeout> attribute after at
least one method call has succeeded. See the C<session_timeout>
attribute for more information.
If no C<'session_timeout'> option is provided, the default
value of 10 seconds (10000 milliseconds) will be used in the
initial connection request; again, the actual timeout period to
which the server agrees will be available subsequently as the
value of the C<session_timeout> attribute.
Upon successful connection (i.e., after the success of a method
which requires communication with the server), the C<session_id>
attribute will hold a short binary string which represents the
client's session ID as set by the server. All ephemeral nodes
created by the session are identified by this ID in the
C<ephemeral_owner> attribute of any Net::ZooKeeper::Stat objects
used to query their state.
The ZooKeeper client code will use this session ID internally
whenever it tries to reconnect to another server in the ZooKeeper
cluster after detecting a failed connection. If it successfully
reconnects with the same session ID, the session will continue
and ephemeral nodes belonging to it will not be deleted.
However, if the server determines that the session has timed
out (for example because no "heartbeat" requests have been
received within the agreed-upon session timeout period), the
session will be terminated by the cluster and all ephemeral nodes
owned by the current session automatically deleted.
On occasion the ZooKeeper client code may not be able to quickly
reconnect to a live server and the caller may want to destroy
the existing Net::ZooKeeper handle object and attempt a
fresh connection using the same session ID as before with a
new Net::ZooKeeper object. To do so, save the C<session_id>
attribute value before undefining the old handle object
and then pass that binary string as the value of the
C<'session_id'> option to the C<new()> method when creating the
next handle object. After the successful completion of a
method which requires communication with the server, if the
new handle object's C<session_id> attribute value matches the
old session ID then the session has been successfully maintained;
otherwise, the old session was expired by the cluster.
=item get_error()
$code = $zkh->get_error();
Returns the ZooKeeper error code, if any, from the most
recent Net::ZooKeeper method invocation. The returned value
will be zero (equivalent to C<ZOK>) if no error occurred,
otherwise non-zero. Non-zero values may be compared to
the error code names exported by the C<:errors> tagset.
See L</Error Handling> for more details.
=item add_auth()
$zkh->add_auth('digest', "$username:$password");
The C<add_auth()> method may be used to add authentication
credentials to a session. Once a credential has been added for
the current session, there is no way to disable it.
When using the digest authentication scheme, note that the
username and password are transmitted in cleartext
to the ZooKeeper cluster.
See L</Access Control> for additional details.
=item create()
$path = $zkh->create($req_path, $data);
$path = $zkh->create($req_path, $data,
'flags' => (ZOO_EPHEMERAL | ZOO_SEQUENCE),
'acl' => ZOO_OPEN_ACL_UNSAFE,
'path_read_len' => 100);
Requests that a node be created in the ZooKeeper cluster's
hierarchy with the given path and data. Upon success,
the returns the node's path, otherwise undef.
The path returned by a successful C<create()> method call
may not be the new node's full path as it appears in the
ZooKeeper hierarchy, depending on the length of the actual
path and the value of the handle object's C<path_read_len>
attribute. If the length of the actual path exceeds the
current value of the C<path_read_len> attribute, the path
returned by the C<create()> method will be truncated; note
that the node's path in the ZooKeeper hierarchy is not
affected by this truncation.
Specifying a value for the C<'path_read_len'> option will
temporarily override the value of the C<path_read_len>
attribute for the duration of the C<create()> method.
The flag values available for use with the C<'flags'> option
are C<ZOO_EPHEMERAL> and C<ZOO_SEQUENCE>; both are
included in the C<:flags> tagset. The flags should be
combined with the bitwise OR operator if more than one
is required.
The C<ZOO_EPHEMERAL> flag causes the node to be marked as
ephemeral, meaning it will be automatically deleted if it
still exists when the client's session ends. The
C<ZOO_SEQUENCE> flag causes a unique integer to be appended
to the node's final path component. See the ZooKeeper
documentation for additional advice on how to use these flags.
When creating a node it may be important to define an ACL
for it; to do this, pass a reference to an ACL array (as
described in L</Access Control>) using the C<'acl'> option.
See also the C<:acl_perms> and C<:acls> tagsets for lists
of the available ACL permission flags and pre-defined ACLs.
=item delete()
$ret = $zkh->delete($path);
$ret = $zkh->delete($path, 'version' => $version);
Requests that a node be deleted from the ZooKeeper hierarchy.
Returns true upon success, false otherwise.
If a value for the C<'version'> option is supplied, the node
will only be deleted if its version number matches the given
value. See the C<version> attribute of the Net::ZooKeeper::Stat
class for details on node version numbering.
=item exists()
$ret = $zkh->exists($path);
$ret = $zkh->exists($path, 'stat' => $stat, 'watch' => $watch);
Tests whether a given node exists. Returns true if the node
exists, otherwise false. When the C<exists()> method is successful
but the node does not exist, it returns false, and C<get_error()>
will return C<ZNONODE> until another method is called on the
handle object.
The C<'stat'> option may be used to request that a
Net::ZooKeeper::Stat object be updated with the node's
current state information. The stat object will only be
updated if the node exists and the C<exists()> method
succeeds. The stat object must first have been created
using the C<stat()> method.
The C<'watch'> option may be used to request that a
Net::ZooKeeper::Watch object be assigned to receive
notification of an event which alters the node's data.
The watch object must first have been created using the
C<watch()> method. If the watch object was previously
assigned to receive notifications for another node, it
will be reassigned even if the C<exists()> method fails.
=item get_children()
@child_names = $zkh->get_children($path);
$num_children = $zkh->get_children($path, 'watch' => $watch);
Queries the names or number of the child nodes stored beneath
a given node in the ZooKeeper hierarchy. In a list context,
returns a list of the child nodes' names upon success, otherwise
an empty list. When the C<get_children()> method is successful
but there are no child nodes, it returns an empty list, and
C<get_error()> will return C<ZOK> until another method is called
on the handle object.
In a scalar context, C<get_children()> returns the number
of child nodes upon success, otherwise undef.
The names of the child nodes are simply the final component
of the nodes' paths, i.e., the portion of their path which
follows the path of the given parent node, excluding the
"/" delimiter.
The C<'watch'> option may be used to request that a
Net::ZooKeeper::Watch object be assigned to receive
notification of an event which alters the node's list of
child nodes. The watch object must first have been created
using the C<watch()> method. If the watch object was
previously assigned to receive notifications for another node,
it will be reassigned even if the C<get_children()> method fails.
=item get()
$data = $zkh->get($path);
$data = $zkh->get($path, 'data_read_len' => 100,
'stat' => $stat, 'watch' => $watch);
Queries the data stored in a given node. Returns the
data as a string upon success, otherwise undef. Note
that the data may contain nulls if the node's data is
not a text string.
If the length of the node's data exceeds the current value
of the handle object's C<data_read_len> attribute, the
string returned by the C<get()> method will be truncated;
note that the node's data in the ZooKeeper cluster is not
affected by this truncation.
Specifying a value for the C<'data_read_len'> option will
temporarily override the value of the C<data_read_len>
attribute for the duration of the C<get()> method.
The C<'stat'> option may be used to request that a
Net::ZooKeeper::Stat object be updated with the node's
current state information. The stat object will only be
updated if the C<get()> method succeeds. The stat object
must first have been created using the C<stat()> method.
The C<'watch'> option may be used to request that a
Net::ZooKeeper::Watch object be assigned to receive
notification of an event which alters the node's data.
The watch object must first have been created using the
C<watch()> method. If the watch object was previously
assigned to receive notifications for another node, it
will be reassigned even if the C<get()> method fails.
=item set()
$ret = $zkh->set($path, $data);
$ret = $zkh->set($path, $data, 'version' => $version,
'stat' => $stat);
Requests that a node's data be updated in the ZooKeeper
hierarchy. Returns true upon success, false otherwise.
If a value for the C<'version'> option is supplied, the node's
data will only be updated if its version number matches the
given value. See the C<version> attribute of the
Net::ZooKeeper::Stat class for details on node version numbering.