asir 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. data/.gitignore +11 -0
  2. data/Gemfile +16 -0
  3. data/README.textile +50 -0
  4. data/Rakefile +83 -0
  5. data/VERSION +1 -0
  6. data/asir.gemspec +36 -0
  7. data/asir.riterate.yml +114 -0
  8. data/bin/asir +6 -0
  9. data/doc/Rakefile +8 -0
  10. data/doc/asir-sequence.pic +84 -0
  11. data/doc/asir-sequence.svg +1559 -0
  12. data/doc/sequence.pic +430 -0
  13. data/example/asir_control.sh +24 -0
  14. data/example/asir_control_client_http.rb +14 -0
  15. data/example/asir_control_client_zmq.rb +15 -0
  16. data/example/config/asir_config.rb +63 -0
  17. data/example/delayed_service.rb +15 -0
  18. data/example/ex01.rb +12 -0
  19. data/example/ex02.rb +12 -0
  20. data/example/ex03.rb +19 -0
  21. data/example/ex04.rb +33 -0
  22. data/example/ex05.rb +16 -0
  23. data/example/ex06.rb +26 -0
  24. data/example/ex07.rb +28 -0
  25. data/example/ex08.rb +30 -0
  26. data/example/ex09.rb +25 -0
  27. data/example/ex10.rb +24 -0
  28. data/example/ex11.rb +48 -0
  29. data/example/ex12.rb +34 -0
  30. data/example/ex13.rb +35 -0
  31. data/example/ex14.rb +30 -0
  32. data/example/ex15.rb +13 -0
  33. data/example/ex16.rb +33 -0
  34. data/example/ex17.rb +41 -0
  35. data/example/ex18.rb +62 -0
  36. data/example/ex19.rb +32 -0
  37. data/example/ex20.rb +28 -0
  38. data/example/ex21.rb +28 -0
  39. data/example/ex22.rb +15 -0
  40. data/example/ex23.rb +20 -0
  41. data/example/ex24.rb +35 -0
  42. data/example/example_helper.rb +51 -0
  43. data/example/sample_service.rb +162 -0
  44. data/example/unsafe_service.rb +12 -0
  45. data/hack_night/README.txt +18 -0
  46. data/hack_night/exercise/prob-1.rb +18 -0
  47. data/hack_night/exercise/prob-2.rb +21 -0
  48. data/hack_night/exercise/prob-3.rb +16 -0
  49. data/hack_night/exercise/prob-4.rb +36 -0
  50. data/hack_night/exercise/prob-5.rb +36 -0
  51. data/hack_night/exercise/prob-6.rb +95 -0
  52. data/hack_night/exercise/prob-7.rb +34 -0
  53. data/hack_night/solution/math_service.rb +11 -0
  54. data/hack_night/solution/prob-1.rb +12 -0
  55. data/hack_night/solution/prob-2.rb +15 -0
  56. data/hack_night/solution/prob-3.rb +17 -0
  57. data/hack_night/solution/prob-4.rb +37 -0
  58. data/hack_night/solution/prob-5.rb +21 -0
  59. data/hack_night/solution/prob-6.rb +33 -0
  60. data/hack_night/solution/prob-7.rb +36 -0
  61. data/lab/phony_proc.rb +31 -0
  62. data/lib/asir.rb +253 -0
  63. data/lib/asir/additional_data.rb +25 -0
  64. data/lib/asir/channel.rb +130 -0
  65. data/lib/asir/client.rb +111 -0
  66. data/lib/asir/code_block.rb +57 -0
  67. data/lib/asir/code_more.rb +50 -0
  68. data/lib/asir/coder.rb +26 -0
  69. data/lib/asir/coder/base64.rb +19 -0
  70. data/lib/asir/coder/chain.rb +30 -0
  71. data/lib/asir/coder/identity.rb +23 -0
  72. data/lib/asir/coder/json.rb +30 -0
  73. data/lib/asir/coder/marshal.rb +17 -0
  74. data/lib/asir/coder/null.rb +23 -0
  75. data/lib/asir/coder/proc.rb +22 -0
  76. data/lib/asir/coder/sign.rb +48 -0
  77. data/lib/asir/coder/xml.rb +213 -0
  78. data/lib/asir/coder/yaml.rb +33 -0
  79. data/lib/asir/coder/zlib.rb +21 -0
  80. data/lib/asir/configuration.rb +32 -0
  81. data/lib/asir/error.rb +34 -0
  82. data/lib/asir/identity.rb +36 -0
  83. data/lib/asir/initialization.rb +23 -0
  84. data/lib/asir/log.rb +82 -0
  85. data/lib/asir/main.rb +396 -0
  86. data/lib/asir/message.rb +31 -0
  87. data/lib/asir/message/delay.rb +35 -0
  88. data/lib/asir/object_resolving.rb +15 -0
  89. data/lib/asir/result.rb +39 -0
  90. data/lib/asir/retry_behavior.rb +54 -0
  91. data/lib/asir/transport.rb +241 -0
  92. data/lib/asir/transport/beanstalk.rb +217 -0
  93. data/lib/asir/transport/broadcast.rb +34 -0
  94. data/lib/asir/transport/buffer.rb +115 -0
  95. data/lib/asir/transport/composite.rb +19 -0
  96. data/lib/asir/transport/connection_oriented.rb +180 -0
  97. data/lib/asir/transport/delay.rb +38 -0
  98. data/lib/asir/transport/delegation.rb +53 -0
  99. data/lib/asir/transport/fallback.rb +36 -0
  100. data/lib/asir/transport/file.rb +88 -0
  101. data/lib/asir/transport/http.rb +54 -0
  102. data/lib/asir/transport/local.rb +21 -0
  103. data/lib/asir/transport/null.rb +14 -0
  104. data/lib/asir/transport/payload_io.rb +52 -0
  105. data/lib/asir/transport/rack.rb +73 -0
  106. data/lib/asir/transport/retry.rb +41 -0
  107. data/lib/asir/transport/stream.rb +35 -0
  108. data/lib/asir/transport/subprocess.rb +30 -0
  109. data/lib/asir/transport/tcp_socket.rb +34 -0
  110. data/lib/asir/transport/webrick.rb +50 -0
  111. data/lib/asir/transport/zmq.rb +110 -0
  112. data/lib/asir/uuid.rb +32 -0
  113. data/lib/asir/version.rb +3 -0
  114. data/spec/const_get_speed_spec.rb +33 -0
  115. data/spec/debug_helper.rb +20 -0
  116. data/spec/example_spec.rb +88 -0
  117. data/spec/json_spec.rb +128 -0
  118. data/spec/spec_helper.rb +3 -0
  119. data/spec/xml_spec.rb +144 -0
  120. data/stylesheets/slides.css +105 -0
  121. metadata +173 -0
@@ -0,0 +1,12 @@
1
+ require 'asir'
2
+
3
+ module UnsafeService
4
+ include ASIR::Client
5
+ def self.do_it(expr)
6
+ result = eval(expr)
7
+ puts "#{$$}: UnsafeService.do_it(#{expr}) #{result.inspect}"
8
+ $stderr.puts "#{$$}: UnsafeService.do_it => #{result.inspect}"
9
+ result
10
+ end
11
+ end
12
+
@@ -0,0 +1,18 @@
1
+ These exercises will introduce ASIR and its concepts.
2
+ Slides:
3
+ http://kurtstephens.com/pub/ruby/abstracting_services_in_ruby/asir.slides/
4
+ git clone git://github.com/kstephens/abstracting_services_in_ruby.git
5
+ Gems: httpclient, libxml-ruby
6
+
7
+ * Writing a service as a ruby Module.
8
+ * Using the default ASIR Coder and Transport to access a service using a client Proxy.
9
+ * Using a Subprocess Transport.
10
+ * Creating new Coders.
11
+ * Creating an HTTP transport using HTTPClient and WEBrick.
12
+ * Chaining Coders.
13
+ * Using Broadcast Transports for logging.
14
+
15
+ Read the slides for more info or ask questions.
16
+ Read the examples/*.rb files for basic examples.
17
+ See the hack_night/example/ files.
18
+ Peek at solutions in the solution/ dir.
@@ -0,0 +1,18 @@
1
+ # prob-1.rb
2
+ # Write a MathService module that has a method that can sum an Array of Numbers
3
+ # It should raise an exception if not given an Array.
4
+ # It should raise an exception if any elements are not Numeric.
5
+
6
+ module MathService
7
+ def sum array_of_numbers
8
+ # ???
9
+ end
10
+ extend self
11
+ end
12
+
13
+ ######################################################################
14
+
15
+ begin
16
+ puts MathService.sum([1, 2, 3]) # => 6
17
+ end
18
+
@@ -0,0 +1,21 @@
1
+ # Call the MathService using the ASIR::Client mixin.
2
+ # Assume the default Transport and Coder.
3
+
4
+ $: << File.expand_path("../../../lib", __FILE__)
5
+ require 'asir'
6
+
7
+ module MathService
8
+ include # ???
9
+ def sum array_of_numbers
10
+ # ???
11
+ end
12
+ extend self
13
+ end
14
+
15
+ ######################################################################
16
+ # Driver:
17
+
18
+ begin
19
+ puts MathService # ??? # => 6
20
+ end
21
+
@@ -0,0 +1,16 @@
1
+ # Call the MathService using the ASIR::Transport::Subprocess mixin.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir'
5
+
6
+ require 'math_service'
7
+ MathService.send(:include, ASIR::Client)
8
+
9
+ ######################################################################
10
+ # Driver:
11
+
12
+ begin
13
+ MathService.client.transport = # ???
14
+ MathService.client.transport._log_enabled = true
15
+ puts MathService.client.sum([1, 2, 3])
16
+ end
@@ -0,0 +1,36 @@
1
+ # Write a Coder that can encode an Array of Numbers as a String and decode a String into a Number.
2
+ # Hint: inspect .vs. eval
3
+
4
+ $: << File.expand_path("../../../lib", __FILE__)
5
+ require 'asir'
6
+
7
+ module ASIR
8
+ class Coder
9
+ class Simple < self
10
+ def _encode obj
11
+ # ???
12
+ end
13
+ def _decode obj
14
+ raise TypeError unless String === obj
15
+ # ???
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ######################################################################
22
+
23
+ begin
24
+ input = [ 1, 2, 3 ]
25
+ puts "input = #{input.inspect}"
26
+
27
+ coder = ASIR::Coder::Simple.new
28
+ coder._log_enabled = true
29
+
30
+ output = coder.encode(input)
31
+ puts "output = #{output.inspect}"
32
+
33
+ result = coder.decode(output)
34
+ puts "result = #{result.inspect}"
35
+ end
36
+
@@ -0,0 +1,36 @@
1
+ # Write a Base64 Coder.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir'
5
+
6
+ module ASIR
7
+ class Coder
8
+ class Base64 < self
9
+ def _encode obj
10
+ raise TypeError unless String === obj
11
+ # ???
12
+ end
13
+
14
+ def _decode obj
15
+ raise TypeError unless String === obj
16
+ # ???
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ ######################################################################
23
+
24
+ begin
25
+ input = "abc123"
26
+ puts "input = #{input.inspect}"
27
+
28
+ coder = ASIR::Coder::Base64.new
29
+ coder._log_enabled = true
30
+
31
+ output = coder.encode(input)
32
+ puts "output = #{output.inspect}"
33
+
34
+ result = coder.decode(output)
35
+ puts "result = #{result.inspect}"
36
+ end
@@ -0,0 +1,95 @@
1
+ # Write a ASIR::Transport::HTTP class.
2
+ # Using HTTP::Client for transport send_message and receive_result.
3
+ # Using WEBrick for transport on the receive_message and send_result.
4
+ # Use the Marshal Coder for the Transport.
5
+
6
+ require 'rubygems'
7
+ require 'webrick'
8
+ gem 'httpclient'
9
+ require 'httpclient'
10
+ require 'uri'
11
+
12
+ $: << File.expand_path("../../../lib", __FILE__)
13
+ require 'asir'
14
+
15
+ require 'math_service'
16
+
17
+ module ASIR
18
+ class Transport
19
+ class HTTP < self
20
+ attr_accessor :uri, :server, :debug
21
+
22
+ # Client-side: HTTPClient
23
+
24
+ # Should HTTP put the request payload String to the uri.
25
+ # Return the HTTPClient result Message object.
26
+ def _send_message message, message_payload
27
+ client = ::HTTPClient.new
28
+ # ???
29
+ end
30
+
31
+ # Should extract the content from the HTTPClient::Respone
32
+ def _receive_result httpclient_response_message
33
+ # ???
34
+ end
35
+
36
+ # Server-side: WEBrick
37
+
38
+ # Extract the body from the WEBrick request.
39
+ def _receive_message webrick_request
40
+ # ???
41
+ end
42
+
43
+ # Set the WEBrick response Content-Type.
44
+ # Set the WEBrick response body with the result_payload String.
45
+ def _send_result result_payload, webrick_result
46
+ # ???
47
+ end
48
+
49
+ # Parse the port and path of the #uri.
50
+ # Create a @server = WEBrick::HTTPServer on the port.
51
+ # Mount the path with a proc that calls serve_request! with the HTTP request and response objects.
52
+ def setup_webrick_server!
53
+ # ???
54
+ self
55
+ end
56
+
57
+ # Start the WEBbrick @server.
58
+ def start_webrick_server!
59
+ # ???
60
+ self
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+ port = 3001
68
+ begin
69
+ t = # ???
70
+ t._log_enabled = true
71
+
72
+ c = t.encoder = ASIR::Coder::Marshal.new
73
+ c._log_enabled = true
74
+
75
+ # Setup and start the WEBrick server in a child process.
76
+ server_pid = Process.fork do
77
+ # ???
78
+ # ???
79
+ end
80
+ sleep 1 # wait for server to start
81
+
82
+ # system("curl http://localhost:#{port}/")
83
+
84
+ MathService.client.transport = t
85
+
86
+ MathService.client.sum([1, 2, 3])
87
+
88
+ rescue Exception => err
89
+ $stderr.puts "ERROR: #{err.inspect}\n#{err.backtrace * "\n"}"
90
+
91
+ ensure
92
+ # Kill the server.
93
+ sleep 1
94
+ Process.kill(9, server_pid)
95
+ end
@@ -0,0 +1,34 @@
1
+ # Use the Marshal and Base64 coders with the HTTP transport.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir_transport_http'
5
+ require 'asir_coder_base64'
6
+
7
+ require 'math_service'
8
+ MathService.send(:include, ASIR::Client)
9
+
10
+ port = 3001
11
+ begin
12
+ t = ASIR::Transport::HTTP.new(:uri => "http://localhost:#{port}")
13
+ t._log_enabled = true
14
+
15
+ c = t.encoder = ASIR::Coder::# ???.new(:encoders => ???)
16
+ c._log_enabled = true
17
+
18
+ server_pid = Process.fork do
19
+ t.setup_server!
20
+ t.start_server!
21
+ end
22
+ sleep 1 # wait for server to start
23
+
24
+ MathService.client.transport = t
25
+ MathService.client.sum([1, 2, 3])
26
+
27
+ rescue Exception => err
28
+ $stderr.puts "ERROR: #{err.inspect}\n#{err.backtrace * "\n"}"
29
+
30
+ ensure
31
+ sleep 1 # wait for server to finish
32
+ Process.kill(9, server_pid)
33
+ end
34
+
@@ -0,0 +1,11 @@
1
+
2
+ module MathService
3
+ def sum array_of_numbers
4
+ raise TypeError unless Array === array_of_numbers
5
+ array_of_numbers.inject(0) do | s, e |
6
+ raise TypeError unless Numeric === e
7
+ s += e
8
+ end
9
+ end
10
+ extend self
11
+ end
@@ -0,0 +1,12 @@
1
+ # Write a MathService module that has a method that can sum an Array of Numbers
2
+ # It should raise an exception if not given an Array.
3
+ # It should raise an exception if any elements are not Numeric.
4
+
5
+ require 'math_service'
6
+
7
+ ######################################################################
8
+
9
+ begin
10
+ puts MathService.sum([1, 2, 3]) # => 6
11
+ end
12
+
@@ -0,0 +1,15 @@
1
+ # Call the MathService using the ASIR::Client mixin.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir'
5
+
6
+ require 'math_service'
7
+ MathService.send(:include, ASIR::Client)
8
+
9
+ ######################################################################
10
+ # Driver:
11
+
12
+ begin
13
+ MathService.client.transport._log_enabled = true
14
+ puts MathService.client.sum([1, 2, 3])
15
+ end
@@ -0,0 +1,17 @@
1
+ # Call the MathService using the ASIR::Transport::Subprocess mixin.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir'
5
+ require 'asir/transport/subprocess'
6
+
7
+ require 'math_service'
8
+ MathService.send(:include, ASIR::Client)
9
+
10
+ ######################################################################
11
+ # Driver:
12
+
13
+ begin
14
+ MathService.client.transport = ASIR::Transport::Subprocess.new
15
+ MathService.client.transport._log_enabled = true
16
+ puts MathService.client.sum([1, 2, 3])
17
+ end
@@ -0,0 +1,37 @@
1
+ # Write a Coder that can encode an Array of Numbers as a String and decode a String into a Number.
2
+ # Hint: inspect .vs. eval
3
+
4
+ $: << File.expand_path("../../../lib", __FILE__)
5
+ require 'asir'
6
+
7
+ module ASIR
8
+ class Coder
9
+ class Simple < self
10
+ def _encode obj
11
+ obj.inspect
12
+ end
13
+
14
+ def _decode obj
15
+ raise TypeError unless String === obj
16
+ Object.send(:eval, obj)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ ######################################################################
23
+
24
+ begin
25
+ input = [ 1, 2, 3 ]
26
+ puts "input = #{input.inspect}"
27
+
28
+ coder = ASIR::Coder::Simple.new
29
+ coder._log_enabled = true
30
+
31
+ output = coder.encode(input)
32
+ puts "output = #{output.inspect}"
33
+
34
+ result = coder.decode(output)
35
+ puts "result = #{result.inspect}"
36
+ end
37
+
@@ -0,0 +1,21 @@
1
+ # Write a Base64 Coder
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir/coder/base64'
5
+
6
+ ######################################################################
7
+
8
+ begin
9
+ input = "abc123"
10
+ puts "input = #{input.inspect}"
11
+
12
+ coder = ASIR::Coder::Base64.new
13
+ coder._log_enabled = true
14
+
15
+ output = coder.encode(input)
16
+ puts "output = #{output.inspect}"
17
+
18
+ result = coder.decode(output)
19
+ puts "result = #{result.inspect}"
20
+ end
21
+
@@ -0,0 +1,33 @@
1
+ # Write a ASIR::Transport::HTTP class that uses HTTP::Client for transport send_result and receive_result.
2
+
3
+ $: << File.expand_path("../../../lib", __FILE__)
4
+ require 'asir/transport/http'
5
+ require 'asir/coder/marshal'
6
+
7
+ require 'math_service'
8
+ MathService.send(:include, ASIR::Client)
9
+
10
+ port = 3001
11
+ begin
12
+ t = ASIR::Transport::HTTP.new(:uri => "http://localhost:#{port}/")
13
+ t._log_enabled = true
14
+ c = t.encoder = ASIR::Coder::Marshal.new
15
+ c._log_enabled = true
16
+
17
+ server_pid = Process.fork do
18
+ t.setup_webrick_server!
19
+ t.start_webrick_server!
20
+ end
21
+ sleep 1 # wait for server to start
22
+
23
+ MathService.client.transport = t
24
+ MathService.client.sum([1, 2, 3])
25
+
26
+ rescue Exception => err
27
+ $stderr.puts "ERROR: #{err.inspect}\n#{err.backtrace * "\n"}"
28
+
29
+ ensure
30
+ sleep 1
31
+ Process.kill(9, server_pid)
32
+ end
33
+