zkruby 3.4.3

Sign up to get free protection for your applications and to get access to all the features.
Binary file
File without changes
@@ -0,0 +1,18 @@
1
+ === 3.4.3 /
2
+
3
+ * Tidy up
4
+
5
+ * simplify require statements (zkruby or em_zkruby)
6
+
7
+ * no need to separately require util recipes for recursive mkpath/rmpath
8
+
9
+ * specs can be run independently
10
+
11
+ * fix dependencies so rake newb works
12
+
13
+ * Use standard major.minor.build versioning. Major/Minor will track ZooKeeper itself, build is zkruby's
14
+
15
+ === 3.4.2.0 / 2012-02/05
16
+
17
+ * First gem release. Tested against Zookeeper 3.4.2, and 3.3.3
18
+
@@ -0,0 +1,39 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ jute/jute.citrus
6
+ jute/lib/hoe/jute.rb
7
+ jute/lib/jute.rb
8
+ lib/zkruby/bindata.rb
9
+ lib/zkruby/enum.rb
10
+ lib/zkruby/eventmachine.rb
11
+ lib/zkruby/multi.rb
12
+ lib/zkruby/protocol.rb
13
+ lib/zkruby/rubyio.rb
14
+ lib/zkruby/session.rb
15
+ lib/zkruby/client.rb
16
+ lib/zkruby/util.rb
17
+ lib/zkruby/zkruby.rb
18
+ lib/zkruby.rb
19
+ lib/em_zkruby.rb
20
+ spec/bindata_spec.rb
21
+ spec/enum_spec.rb
22
+ spec/eventmachine_spec.rb
23
+ spec/multi_spec.rb
24
+ spec/protocol_spec.rb
25
+ spec/recipe_helper.rb
26
+ spec/rubyio_spec.rb
27
+ spec/sequences_spec.rb
28
+ spec/shared/auth.rb
29
+ spec/shared/basic.rb
30
+ spec/shared/binding.rb
31
+ spec/shared/chroot.rb
32
+ spec/shared/multi.rb
33
+ spec/shared/util.rb
34
+ spec/shared/watch.rb
35
+ spec/spec_helper.rb
36
+ spec/server_helper.rb
37
+ src/jute/zookeeper.jute
38
+ lib/jute/zookeeper.rb
39
+ yard_ext/enum_handler.rb
@@ -0,0 +1,119 @@
1
+ = zkruby
2
+
3
+ * https://github.com/lwoggardner/zkruby
4
+
5
+ == DESCRIPTION:
6
+
7
+ Pure ruby client for ZooKeeper (http://zookeeper.apache.org)
8
+
9
+ == FEATURES
10
+
11
+ Supports full ZooKeeper API, synchronous or asynchronous style, watches etc.. with implementations over EventMachine or plain old Ruby IO/Threads
12
+
13
+ Advantages:
14
+ * Rubyist API - with block is asynchronous, without block is synchronous
15
+ * Avoids conflicts between various Ruby threading models and the C/Java apis
16
+ * Same code for JRuby or MRI
17
+ * Connection bindings for pure ruby IO and eventmachine, or roll your own
18
+
19
+ Disadvantages:
20
+ * Duplicated code from Java/C libraries, particularly around herd effect protection
21
+ * Maintain in parallel with breaking changes in protocol which are possibly more likely
22
+ than breaking changes in the client API
23
+ * Probably not as optimised in terms of performance (but your client code is ruby anyway)
24
+ * Not production tested (yet- do you want to be the first?)
25
+
26
+ == SYNOPSIS:
27
+
28
+ 0. Configure Slf4R Logging (https://rubygems.org/gems/slf4r)
29
+ 1. Get a connection {ZooKeeper.connect}
30
+ 2. Make requests on the returned {ZooKeeper::Client}
31
+
32
+ require 'slf4r/ruby_logging'
33
+ require 'zkruby'
34
+
35
+ # Using ruby threads and sockets (default)
36
+ zk = ZooKeeper.connect("localhost:2181")
37
+ # Synchronous
38
+ stat = zk.exists("/aPath")
39
+
40
+ # Asynchronous
41
+ zk.exists("/aPath) { |stat| puts stat.inspect }
42
+
43
+ # Watches
44
+ watch = lambda { |state,path,event| puts "Watch fired #{state} #{path} #{event}" }
45
+
46
+ stat,data = zk.get("/aPath",watch)
47
+
48
+ # OR with EventMachine
49
+ require 'em_zkruby'
50
+ EventMachine.run do
51
+ # Magic of Fibers (via Strands) lets us code normally and execute asynchronously
52
+ Strand.new() do
53
+ begin
54
+ zk = ZooKeeper.connect("localhost:2181")
55
+ #Sync
56
+ path = zk.create("/aPath/mynode",ZK::ACL_ANYONE_UNSAFE,:ephemeral,:sequential)
57
+
58
+ #Async
59
+ zk.get(path) do |stat,data|
60
+ puts "#{stat.inspect} #{data}"
61
+ end
62
+
63
+ rescue ZooKeeper::Error => zkex
64
+ puts zkex.message
65
+ end
66
+ end
67
+ end
68
+
69
+ == REQUIREMENTS:
70
+
71
+ * A ZooKeeper cluster to connect to
72
+ * Ruby 1.9 (but a backport should be straightforward)
73
+
74
+ == INSTALL:
75
+
76
+ $ (sudo) gem install zkruby
77
+
78
+ == DEVELOPERS:
79
+
80
+ Checkout the zookeeper source from http://zookeeper.apache.org
81
+
82
+ Checkout the zkruby source into the contrib directory
83
+
84
+ Install hoe
85
+
86
+ $ (sudo) gem install hoe
87
+
88
+ Install other dependencies
89
+
90
+ $ rake check_extra_deps
91
+
92
+ Generate docs and run the tests/specs
93
+
94
+ $ rake newb
95
+
96
+ == LICENSE:
97
+
98
+ (The MIT License)
99
+
100
+ Copyright (c) 2011
101
+
102
+ Permission is hereby granted, free of charge, to any person obtaining
103
+ a copy of this software and associated documentation files (the
104
+ 'Software'), to deal in the Software without restriction, including
105
+ without limitation the rights to use, copy, modify, merge, publish,
106
+ distribute, sublicense, and/or sell copies of the Software, and to
107
+ permit persons to whom the Software is furnished to do so, subject to
108
+ the following conditions:
109
+
110
+ The above copyright notice and this permission notice shall be
111
+ included in all copies or substantial portions of the Software.
112
+
113
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
114
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
115
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
116
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
117
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
118
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
119
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # -*- ruby -*-
2
+ # hoe 2.12.5 goes looking for the plugins so we have to do it this way..
3
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/jute/lib'
4
+
5
+ require 'rubygems'
6
+ require 'hoe'
7
+
8
+ begin
9
+ require './yard_ext/enum_handler'
10
+ rescue LoadError => err
11
+ warn "%p while trying to load yard extensions: %s" % [ err.class, err.message ]
12
+ end
13
+
14
+
15
+
16
+ # Hoe.plugin :compiler
17
+ #Hoe.plugin :gem_prelude_sucks
18
+ Hoe.plugin :git
19
+ # Hoe.plugin :inline
20
+ # Hoe.plugin :racc
21
+ # Hoe.plugin :rubyforge
22
+ Hoe.plugin :yard
23
+ Hoe.plugin :jute
24
+
25
+ Hoe.spec 'zkruby' do
26
+ self.readme_file="README.rdoc"
27
+ developer('Grant Gardner', 'grant@lastweekend.com.au')
28
+ dependency 'slf4r' , '~> 0.4.2'
29
+ dependency 'eventmachine', '~> 0.12.10', :development
30
+ dependency 'strand', '~> 0.1.0', :development
31
+ dependency 'logging', '>= 1.4.1', :development
32
+ dependency 'rspec', '>=2.7.0', :development
33
+ dependency 'hoe-yard', '>=0.1.2', :development
34
+
35
+ self.jute_modules = {
36
+ "org.apache.zookeeper.data" => "ZooKeeper::Data",
37
+ "org.apache.zookeeper.proto" => "ZooKeeper::Proto"}
38
+ end
39
+ # vim: syntax=ruby
@@ -0,0 +1,105 @@
1
+ grammar Jute
2
+
3
+ rule jute
4
+ (space* jmodule*) {
5
+
6
+ captures[:jmodule].inject(Hash.new()) do |h,m|
7
+ h[m.name.value] = m.classes
8
+ h
9
+ end
10
+ }
11
+ end
12
+
13
+ rule jmodule
14
+ ('module' (space)1* name:identifier space* '{' space* jclass* '}' space*) {
15
+
16
+ def value
17
+ [ name.value, classes() ]
18
+ end
19
+
20
+ def classes
21
+ captures[:jclass].inject(Hash.new()) do |h,c|
22
+ h[c.name.value] = c.jfields
23
+ h
24
+ end
25
+ end
26
+
27
+ }
28
+ end
29
+
30
+ rule jclass
31
+ ('class' (space)1* name:class_identifier space* '{' space* jfield* '}' space*) {
32
+
33
+ def jfields
34
+ # field order is important!
35
+ captures[:jfield].collect() do |f|
36
+ f.value
37
+ end
38
+ end
39
+ }
40
+ end
41
+
42
+ rule jfield
43
+ (ftype name:identifier space* ';' space*) {
44
+ [ name.value, ftype.value ]
45
+ }
46
+ end
47
+
48
+ rule ftype
49
+ (parameterized_type | non_parameterized_type)
50
+ end
51
+
52
+ rule parameterized_type
53
+ vector
54
+ end
55
+
56
+ rule non_parameterized_type
57
+ (basic_type (space)1*)
58
+ {
59
+ basic_type.value
60
+ }
61
+ end
62
+
63
+ rule basic_type
64
+ (primitive_type | nested_record)
65
+ end
66
+
67
+ rule primitive_type
68
+ ('int' | 'long' | 'boolean' | 'byte' | 'float' | 'double' | 'ustring' | 'buffer') {
69
+ to_sym
70
+ }
71
+ end
72
+
73
+ rule vector
74
+ ('vector' space* '<' space* vtype:(basic_type | parameterized_type) space* '>' space*) {
75
+ [ :vector, vtype.value ]
76
+ }
77
+ end
78
+
79
+ rule nested_record
80
+ identifier {
81
+ components = split(".")
82
+ module_name = components[0..-2].join(".") if components.length > 1
83
+ class_name = components.last
84
+ [ :record, module_name, class_name ]
85
+ }
86
+ end
87
+
88
+ rule space
89
+ [ \t\r\n] | line_comment | block_comment
90
+ end
91
+
92
+ rule line_comment
93
+ '//' (!eol .)* (eol | eof) space*
94
+ end
95
+
96
+ rule block_comment
97
+ '/*' (!'*/' .)* '*/' space*
98
+ end
99
+
100
+ rule class_identifier [a-zA-Z0-9_]1* end
101
+ rule identifier [a-zA-Z0-9_.]1* end
102
+ rule eof !. end
103
+ rule eol [\r\n] end
104
+
105
+ end
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+
3
+ module Hoe::Jute
4
+ attr_accessor :jute
5
+ attr_accessor :jute_tasks
6
+ attr_accessor :jute_modules
7
+
8
+ #attr_accessor :jute_compiler
9
+ def initialize_jute
10
+ self.jute_tasks = [:test,:spec,:package]
11
+ dependency 'citrus', '~> 2.4.0', :development
12
+ #dependency 'jute' # if jute is ever a separate gem
13
+ dependency 'bindata', '~> 1.4.1'
14
+ end
15
+
16
+ def define_jute_tasks
17
+
18
+ found = try_load_jute()
19
+
20
+ if found
21
+ jute_compiler = ::Jute::Compiler.new()
22
+ jute_files = self.spec.files.find_all { |f| f =~ /\.jute$/ }
23
+
24
+ record_files = jute_files.map { |f| f.pathmap("%{src,lib}X.rb") }
25
+ self.clean_globs += record_files
26
+
27
+
28
+ rule ".rb" => ["%{lib,src}X.jute"] do |t|
29
+ File.open(t.source) do |input|
30
+ File.open(t.name,"w") do |output|
31
+ puts "compiling #{input.inspect} to #{output.inspect}"
32
+ jute_compiler.compile(input,output,jute_modules)
33
+ end
34
+ end
35
+ end
36
+
37
+ desc "generate jute records" unless jute_files.empty?
38
+ task :jute
39
+
40
+ task :jute => record_files
41
+
42
+ jute_tasks.each do |t|
43
+ task t => [:jute]
44
+ end
45
+ end
46
+ end
47
+
48
+ def try_load_jute()
49
+ require 'jute'
50
+ rescue LoadError => err
51
+ warn "%p while trying to load jute: %s" % [ err.class, err.message ]
52
+ false
53
+ end
54
+ end
55
+
56
+
@@ -0,0 +1,120 @@
1
+ # coding: utf-8
2
+ require 'citrus'
3
+
4
+ class String
5
+ def to_snake_case!
6
+ self.gsub!(/(.)([A-Z])/,'\1_\2')
7
+ self.downcase!
8
+ end
9
+
10
+ def to_snake_case
11
+ self.clone.to_underscore!
12
+ end
13
+ end
14
+
15
+ Citrus.load(File.dirname(__FILE__) + "/../jute.citrus")
16
+
17
+ JUTE_TO_BINDATA = { :int => "int32be",
18
+ :long => "int64be",
19
+ :ustring => "zk_string",
20
+ :boolean => "zk_boolean",
21
+ :buffer => "zk_buffer",
22
+ :float => "float_be",
23
+ :double => "double_be" }
24
+
25
+ module Jute
26
+ class Compiler
27
+
28
+ attr_reader :invalid_names
29
+
30
+ def initialize()
31
+ @invalid_names = {
32
+ "max" => "maximum",
33
+ "id" => "identity",
34
+ "Id" => "Identity",
35
+ "type" => "_type"
36
+ }
37
+ @selected_modules = {}
38
+ end
39
+
40
+ def compile(input,out,selected_modules={})
41
+
42
+ contents = input.read
43
+ modules = Jute.parse(contents).value
44
+
45
+ if (selected_modules.size > 0)
46
+ modules = modules.select() do |k,v|
47
+ selected_modules.has_key?(k)
48
+ end
49
+ end
50
+
51
+ modules.each_pair do | mod_name, mod_info |
52
+
53
+ out << " module #{selected_modules[mod_name]}\n"
54
+
55
+ mod_info.each_pair do | record_name, record_info |
56
+ record_name = classify(record_name)
57
+ out << " class #{record_name} < BinData::Record\n"
58
+
59
+ record_info.each do | field_info |
60
+ field_name, field_type = field_info
61
+ field_name = invalid_names[field_name] || field_name
62
+ field_name.to_snake_case!
63
+ case field_type
64
+ when Symbol
65
+ out << " #{JUTE_TO_BINDATA[field_type]} :#{field_name}\n"
66
+ when Array
67
+ complex_type, *type_args = field_type
68
+ send(complex_type, out, field_name, *type_args)
69
+ else
70
+ out << field_info.inspect << "\n"
71
+ end
72
+ end
73
+
74
+ out << " end\n"
75
+ end
76
+
77
+ out << " end\n"
78
+ end
79
+ end
80
+
81
+ def vector(out, name,contained_type)
82
+ case contained_type
83
+ when Symbol
84
+ out << " hide :#{name}__length\n"
85
+ out << " int32be :#{name}__length, :value => lambda { #{name}.length }\n"
86
+ out << " array :#{name}, :type => :#{JUTE_TO_BINDATA[contained_type]}, :initial_length => :#{name}__length\n"
87
+ when Array
88
+ complex_type, *type_args = contained_type
89
+ if (complex_type == :record)
90
+ out << " hide :#{name}__length\n"
91
+ out << " int32be :#{name}__length, :value => lambda { #{name}.length }\n"
92
+ out << " array :#{name}, :type => :#{type_args[1].downcase}, :initial_length => :#{name}__length\n"
93
+ else
94
+ #TODO raise typerror
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ # TODO handle modules, for now the record_names must be unique
101
+ def record(out, field_name, module_name, record_name)
102
+ record_name = invalid_names[record_name] || record_name
103
+ out << " #{record_name.downcase()} :#{field_name}\n"
104
+ end
105
+
106
+ # turn a record name into a legitimate ruby class name
107
+ def classify(record_name)
108
+ record_name = invalid_names[record_name] || record_name
109
+ return record_name.gsub(/(^|_)(.)/) { $2.upcase }
110
+ end
111
+ end #class Compiler
112
+ end #module Jute
113
+ if __FILE__ == $0
114
+ compiler = JuteCompiler.new()
115
+ modules = {
116
+ "org.apache.zookeeper.data" => "ZooKeeper::Data",
117
+ "org.apache.zookeeper.proto" => "ZooKeeper::Proto" }
118
+
119
+ compiler.compile(STDIN,STDOUT,modules)
120
+ end