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,30 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Synchronous HTTP service on instance methods.
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/webrick'
6
+ require 'asir/coder/base64'
7
+ begin
8
+ MyClass.client.transport = t =
9
+ ASIR::Transport::Webrick.new(:uri => "http://localhost:30914/")
10
+ t.encoder =
11
+ ASIR::Coder::Chain.new(:encoders =>
12
+ [ ASIR::Coder::Marshal.new,
13
+ ASIR::Coder::Base64.new, ])
14
+ server_process do
15
+ t.prepare_server!
16
+ t.run_server!
17
+ end; sleep 2
18
+ pr MyClass.new("abc123").client.size
19
+ sleep 2
20
+ rescue Object => err
21
+ $stderr.puts "#{err.inspect}\n#{err.backtrace * "\n"}"
22
+ ensure
23
+ t.close; sleep 3; server_kill; sleep 2
24
+ end
25
+
26
+ # !SLIDE END
27
+ # EXPECT: : client process
28
+ # EXPECT: : server process
29
+ # EXPECT: : pr: 6
30
+
@@ -0,0 +1,13 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Local Process with delay option.
3
+
4
+ require 'example_helper'
5
+
6
+ pr DelayedService.client.
7
+ _configure{|req| req.delay = 5}.
8
+ do_it(Time.now)
9
+
10
+ # !SLIDE END
11
+ # EXPECT: : client process
12
+ # EXPECT: DelayedService.do_it => :ok
13
+ # EXPECT: : pr: :ok
@@ -0,0 +1,33 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Asynchronous beanstalkd service with delay option
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/beanstalk'
6
+ begin
7
+ DelayedService.client.transport = t =
8
+ ASIR::Transport::Beanstalk.new(:address => '127.0.0.1', :port => 30916)
9
+ t.encoder =
10
+ ASIR::Coder::Marshal.new
11
+ t.start_beanstalkd!; sleep 1
12
+ server_process do
13
+ t.prepare_beanstalk_server!
14
+ t.run_beanstalk_server!
15
+ end; sleep 1
16
+ pr DelayedService.client.
17
+ _configure{|req| req.delay = 5}.
18
+ do_it(Time.now)
19
+ sleep 10
20
+ rescue Object => err
21
+ $stderr.puts "#{err.inspect}\n#{err.backtrace * "\n"}"
22
+ ensure
23
+ t.close; sleep 1
24
+ server_kill; sleep 1
25
+ t.stop_beanstalkd!
26
+ end
27
+
28
+ # !SLIDE END
29
+ # EXPECT: : client process
30
+ # EXPECT: : server process
31
+ # EXPECT: DelayedService.do_it => :ok
32
+ # EXPECT: : pr: nil
33
+
@@ -0,0 +1,41 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Buffered asynchronous beanstalkd service with delay option
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/beanstalk'
6
+ require 'asir/transport/buffer'
7
+ begin
8
+ t =
9
+ ASIR::Transport::Beanstalk.new(:address => '127.0.0.1', :port => 30917)
10
+ t.encoder =
11
+ ASIR::Coder::Marshal.new
12
+ t.start_beanstalkd!; sleep 1
13
+ DelayedService.client.transport =
14
+ t0 = ASIR::Transport::Buffer.new(:transport => t)
15
+ t0.pause!
16
+ server_process do
17
+ t.prepare_beanstalk_server!
18
+ t.run_beanstalk_server!
19
+ end; sleep 1
20
+ pr [ :paused, t0.paused?, :at, Time.now.iso8601(2) ]
21
+ pr DelayedService.client.
22
+ _configure{|req| req.delay = 5}.
23
+ do_it(Time.now)
24
+ sleep 2
25
+ pr [ :resuming, :size, t0.size, :at, Time.now.iso8601(2) ]
26
+ t0.resume!
27
+ pr [ :paused, t0.paused?, :size, t0.size, :at, Time.now.iso8601(2) ]
28
+ sleep 10
29
+ rescue Object => err
30
+ $stderr.puts "#{err.inspect}\n#{err.backtrace * "\n"}"
31
+ ensure
32
+ t.close; sleep 1; server_kill; sleep 1
33
+ t.stop_beanstalkd!
34
+ end
35
+
36
+ # !SLIDE END
37
+ # EXPECT: : client process
38
+ # EXPECT: : server process
39
+ # EXPECT: DelayedService.do_it => :ok
40
+ # EXPECT: : pr: nil
41
+
@@ -0,0 +1,62 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Socket service with retry.
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/retry'
6
+ begin
7
+ File.unlink(service_log = "#{__FILE__}.service.log") rescue nil
8
+ file = ASIR::Transport::File.new(:file => service_log,
9
+ :encoder => ASIR::Coder::Yaml.new)
10
+ tcp = ASIR::Transport::TcpSocket.new(:port => 31918,
11
+ :encoder => ASIR::Coder::Marshal.new)
12
+ start_server_proc = lambda do | transport, message |
13
+ $stderr.puts "message = #{message.inspect}"
14
+ file.send_message(message)
15
+ server_process do
16
+ tcp.prepare_server!
17
+ tcp.run_server!
18
+ end; sleep 2
19
+ end
20
+ Email.client.transport = t =
21
+ ASIR::Transport::Retry.new(:transport => tcp,
22
+ :try_sleep => 1,
23
+ :try_sleep_increment => 2,
24
+ :try_max => 3,
25
+ :before_retry => start_server_proc
26
+ )
27
+ pr Email.client.send_email(:pdf_invoice,
28
+ :to => "user@email.com", :customer => 123)
29
+ sleep 1
30
+ pr Email.client.send_email(:pdf_invoice,
31
+ :to => "user2@email.com", :customer => 456)
32
+ sleep 1
33
+ rescue ::Exception => err
34
+ $stderr.puts "ERROR: #{err.inspect}\n #{err.backtrace * "\n "}"
35
+ raise
36
+ ensure
37
+ file.close rescue nil;
38
+ tcp.close rescue nil; sleep 1
39
+ server_kill
40
+ puts "\x1a\n#{service_log.inspect} contents:"
41
+ puts File.read(service_log)
42
+ end
43
+
44
+ # !SLIDE END
45
+ # EXPECT: : client process
46
+ # EXPECT: : server process
47
+ # EXPECT/: : Email.send_mail :pdf_invoice .*:to=>"user@email.com"
48
+ # EXPECT/: : Email.send_mail :pdf_invoice .*:to=>"user2@email.com"
49
+ # EXPECT: : pr: :ok
50
+ # EXPECT: service.log" contents:
51
+ # EXPECT: --- !ruby/object:ASIR::Message
52
+ # EXPECT: :transport_exceptions:
53
+ # EXPECT: ASIR::Error: Cannot connect to ASIR::Transport::TcpSocket tcp://127.0.0.1:
54
+ # EXPECT: arguments:
55
+ # EXPECT: - :pdf_invoice
56
+ # EXPECT/: :to: user@email.com
57
+ # EXPECT/: :customer: 123
58
+ # EXPECT!/: :to: user2@email.com
59
+ # EXPECT!/: :customer: 456
60
+ # EXPECT: receiver: Email
61
+ # EXPECT: receiver_class: Module
62
+ # EXPECT: selector: :send_email
@@ -0,0 +1,32 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Socket service with unsafe Exception.
3
+
4
+ require 'example_helper'
5
+ begin
6
+ tcp = ASIR::Transport::TcpSocket.new(:port => 31919,
7
+ :encoder => ASIR::Coder::Marshal.new)
8
+ server_process do
9
+ tcp.prepare_server!
10
+ tcp.run_server!
11
+ end; sleep 2
12
+ UnsafeService.client.transport = t = tcp
13
+ pr UnsafeService.client.do_it("exit 999; :ok")
14
+ sleep 1
15
+ rescue ::ASIR::Error::Unforwardable => err
16
+ $stderr.puts "### #{$$}: Unforwardable ERROR: #{err.inspect}}"
17
+ rescue ::Exception => err
18
+ $stderr.puts "### #{$$}: ERROR: #{err.inspect}\n #{err.backtrace * "\n "}"
19
+ raise
20
+ ensure
21
+ file.close rescue nil;
22
+ tcp.close rescue nil; sleep 1
23
+ server_kill
24
+ # puts "\x1a\n#{service_log.inspect} contents:"
25
+ # puts File.read(service_log)
26
+ end
27
+
28
+ # !SLIDE END
29
+ # EXPECT: : client process
30
+ # EXPECT: : server process
31
+ # EXPECT!: : pr: :ok
32
+ # EXPECT: Unforwardable ERROR: #<ASIR::Error::Unforwardable: SystemExit
@@ -0,0 +1,28 @@
1
+ # !SLIDE :capture_code_output true
2
+ # One-way ZMQ service.
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/zmq'
6
+ begin
7
+ zmq = ASIR::Transport::Zmq.new(:port => 31920,
8
+ :encoder => ASIR::Coder::Marshal.new,
9
+ :one_way => true)
10
+ server_process do
11
+ zmq.prepare_server!
12
+ zmq.run_server!
13
+ end; sleep 1
14
+ UnsafeService.client.transport = t = zmq
15
+ pr UnsafeService.client.do_it(":ok")
16
+ rescue ::Exception => err
17
+ $stderr.puts "### #{$$}: ERROR: #{err.inspect}\n #{err.backtrace * "\n "}"
18
+ raise
19
+ ensure
20
+ zmq.close rescue nil; sleep 1; server_kill
21
+ end
22
+
23
+ # !SLIDE END
24
+ # EXPECT: : client process
25
+ # EXPECT: : server process
26
+ # EXPECT: UnsafeService.do_it => :ok
27
+ # EXPECT: : pr: nil
28
+ # EXPECT!: ERROR
@@ -0,0 +1,28 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Bi-directional ZMQ service.
3
+
4
+ require 'example_helper'
5
+ require 'asir/transport/zmq'
6
+ begin
7
+ zmq = ASIR::Transport::Zmq.new(:port => 31920,
8
+ :encoder => ASIR::Coder::Marshal.new,
9
+ :one_way => false)
10
+ server_process do
11
+ zmq.prepare_server!
12
+ zmq.run_server!
13
+ end; sleep 1
14
+ UnsafeService.client.transport = t = zmq
15
+ pr UnsafeService.client.do_it(":ok")
16
+ rescue ::Exception => err
17
+ $stderr.puts "### #{$$}: ERROR: #{err.inspect}\n #{err.backtrace * "\n "}"
18
+ raise
19
+ ensure
20
+ zmq.close rescue nil; sleep 1; server_kill
21
+ end
22
+
23
+ # !SLIDE END
24
+ # EXPECT: : client process
25
+ # EXPECT: : server process
26
+ # EXPECT: UnsafeService.do_it => :ok
27
+ # EXPECT: : pr: :ok
28
+ # EXPECT!: ERROR
@@ -0,0 +1,15 @@
1
+ # !SLIDE :capture_code_output true
2
+ # In-core, in-process service, with continuation block.
3
+
4
+ require 'example_helper'
5
+ pr(Email.client.send_email(:pdf_invoice,
6
+ :to => "user@email.com",
7
+ :customer => @customer,
8
+ &proc { | res | pr [ :in_block, res.result ] })
9
+ )
10
+
11
+ # !SLIDE END
12
+ # EXPECT: : client process
13
+ # EXPECT: : Email.send_mail :pdf_invoice
14
+ # EXPECT: : pr: :ok
15
+ # EXPECT: : pr: [:in_block, :ok]
@@ -0,0 +1,20 @@
1
+ #
2
+ # !SLIDE :capture_code_output true
3
+ # Subprocess service with continuation
4
+
5
+ require 'example_helper'
6
+ begin
7
+ Email.client.transport = t =
8
+ ASIR::Transport::Subprocess.new(:one_way => true)
9
+ pr(Email.client.send_email(:pdf_invoice,
10
+ :to => "user@email.com",
11
+ :customer => @customer) { | resp |
12
+ pr [ :in_block, resp.result ] })
13
+ end
14
+
15
+ # !SLIDE END
16
+ # EXPECT: : client process
17
+ # EXPECT: : Email.send_mail :pdf_invoice
18
+ # EXPECT: : pr: nil
19
+ # EXPECT: : pr: [:in_block, :ok]
20
+
@@ -0,0 +1,35 @@
1
+ # !SLIDE :capture_code_output true
2
+ # Synchronous HTTP service on Rack under WEBrick
3
+
4
+ gem 'rack'
5
+ require 'example_helper'
6
+ require 'asir/transport/rack'
7
+ require 'asir/coder/base64'
8
+ begin
9
+ Email.client.transport = t =
10
+ ASIR::Transport::Rack.new(:uri => "http://localhost:31924/")
11
+ t.encoder =
12
+ ASIR::Coder::Chain.new(:encoders =>
13
+ [ASIR::Coder::Marshal.new,
14
+ ASIR::Coder::Base64.new, ])
15
+ server_process do
16
+ t.prepare_server!
17
+ t.run_server!
18
+ end; sleep 2
19
+ pr Email.client.send_email(:pdf_invoice,
20
+ :to => "user@email.com",
21
+ :customer => @customer)
22
+ sleep 2
23
+ rescue Object => err
24
+ $stderr.puts "#{err.inspect}\n#{err.backtrace * "\n"}"
25
+ ensure
26
+ t.close rescue nil; sleep 3
27
+ server_kill; sleep 2
28
+ end
29
+
30
+ # !SLIDE END
31
+ # EXPECT: : client process
32
+ # EXPECT: : server process
33
+ # EXPECT: : Email.send_mail :pdf_invoice
34
+ # EXPECT: : pr: :ok
35
+
@@ -0,0 +1,51 @@
1
+ # Sample client support
2
+ #
3
+
4
+ $: << File.expand_path("../../lib", __FILE__)
5
+ require 'asir'
6
+ require 'asir/transport/file'
7
+ require 'asir/transport/local'
8
+ require 'asir/transport/subprocess'
9
+ require 'asir/transport/tcp_socket'
10
+ require 'asir/transport/fallback'
11
+ require 'asir/transport/broadcast'
12
+ require 'asir/coder/marshal'
13
+ require 'asir/coder/yaml'
14
+ require 'asir/coder/sign'
15
+ require 'asir/coder/chain'
16
+ ASIR::Log.enabled = true unless ENV['ASIR_EXAMPLE_SILENT']
17
+ require 'sample_service'
18
+ require 'delayed_service'
19
+ require 'unsafe_service'
20
+
21
+ require 'pp'
22
+ require File.expand_path('../../spec/debug_helper', __FILE__)
23
+
24
+ @customer = 123
25
+
26
+ class ::Object
27
+
28
+ def pr result
29
+ $stdout.puts "*** #{$$}: pr: #{PP.pp(result, '')}"
30
+ end
31
+
32
+ def server_process &blk
33
+ $server_pid = Process.fork do
34
+ puts "*** #{$$}: server process"; $stdout.flush
35
+ yield
36
+ end
37
+ sleep 1 # wait for server to be ready.
38
+ end
39
+
40
+ def server_kill
41
+ if $server_pid
42
+ Process.kill 9, $server_pid
43
+ Process.waitpid($server_pid)
44
+ end
45
+ $server_pid = nil
46
+ end
47
+
48
+ end
49
+
50
+ puts "*** #{$$}: client process"; $stdout.flush
51
+
@@ -0,0 +1,162 @@
1
+ =begin
2
+ # !SLIDE
3
+ # Stuff Gets Complicated
4
+ #
5
+ # Systems become:
6
+ # * bigger ->
7
+ # * complex ->
8
+ # * slower ->
9
+ # * distributed ->
10
+ # * hard to test
11
+ #
12
+ # !SLIDE END
13
+
14
+ # !SLIDE
15
+ # Sample Service
16
+ #
17
+ module Email
18
+ def send_email template_name, options
19
+ $stderr.puts "*** #{$$}: Email.send_mail #{template_name.inspect} #{options.inspect}"
20
+ :ok
21
+ end
22
+ def do_raise msg
23
+ raise msg
24
+ end
25
+ extend self
26
+ end
27
+ # !SLIDE END
28
+
29
+ # !SLIDE
30
+ # Back when things were simple...
31
+ #
32
+ class CustomersController < ApplicationController
33
+ def send_invoice
34
+ @customer = Customer.find(params[:id])
35
+ Email.send_email(:pdf_invoice,
36
+ :to => @customer.email,
37
+ :customer => @customer)
38
+ end
39
+ end
40
+ # !SLIDE END
41
+
42
+ # !SLIDE
43
+ # Trying to improve user's experience...
44
+ #
45
+ class CustomersController < ApplicationController
46
+ def send_invoice
47
+ @customer = Customer.find(params[:id])
48
+ Process.fork do
49
+ Email.send_email(:pdf_invoice,
50
+ :to = @customer.email,
51
+ :customer => @customer)
52
+ end
53
+ end
54
+ end
55
+ # !SLIDE END
56
+
57
+ # !SLIDE
58
+ # Use other machines to poll a work table...
59
+ #
60
+ class CustomersController < ApplicationController
61
+ def send_invoice
62
+ @customer = Customer.find(params[:id])
63
+ EmailWork.create(:template_name => :pdf_invoice,
64
+ :options => {
65
+ :to => @customer.email,
66
+ :customer => @customer,
67
+ })
68
+ end
69
+ end
70
+ # !SLIDE END
71
+
72
+ # !SLIDE
73
+ # Use queue infrastructure
74
+ #
75
+ class CustomersController < ApplicationController
76
+ def send_invoice
77
+ @customer = Customer.find(params[:id])
78
+ queue_service.put(:queue => :Email,
79
+ :action => :send_email,
80
+ :template_name => :pdf_invoice,
81
+ :options => {
82
+ :to => @customer.email,
83
+ :customer => @customer,
84
+ })
85
+ end
86
+ end
87
+ # !SLIDE END
88
+
89
+ # !SLIDE
90
+ # Example Message
91
+ #
92
+ Email.client.send_email(:pdf_invoice,
93
+ :to => "user@email.com",
94
+ :customer => @customer)
95
+ # ->
96
+ message = Message.new(...)
97
+ message.receiver_class == ::Module
98
+ message.receiver == ::Email
99
+ message.selector == :send_email
100
+ message.arguments == [ :pdf_invoice,
101
+ { :to => "user@email.com",
102
+ :customer => ... } ]
103
+ # !SLIDE END
104
+
105
+ # !SLIDE
106
+ # Using a Client Proxy
107
+ #
108
+ Email.send_email(:pdf_invoice,
109
+ :to => "user@email.com",
110
+ :customer => @customer)
111
+ # ->
112
+ Email.client.
113
+ send_email(:pdf_invoice,
114
+ :to => "user@email.com",
115
+ :customer => @customer)
116
+ # !SLIDE END
117
+
118
+ # !SLIDE
119
+ # Example Exception
120
+ #
121
+ Email.do_raise("DOH!")
122
+ #
123
+ # ->
124
+ result.exception = ee = EncapsulatedException.new(...)
125
+ ee.exception_class = "::RuntimeError"
126
+ ee.exception_message = "DOH!"
127
+ ee.exception_backtrace = [ ... ]
128
+ # !SLIDE END
129
+ =end
130
+
131
+ # !SLIDE
132
+ # Sample Service with Client Support
133
+ #
134
+
135
+ require 'asir'
136
+ # Added .client support.
137
+ module Email
138
+ include ASIR::Client # Email.client
139
+ def send_email template_name, options
140
+ $stderr.puts "*** #{$$}: Email.send_mail #{template_name.inspect} #{options.inspect}"
141
+ :ok
142
+ end
143
+ def do_raise msg
144
+ raise msg
145
+ end
146
+ extend self
147
+ end
148
+ # !SLIDE END
149
+
150
+ # !SLIDE
151
+ # Sample Object Instance Client
152
+ #
153
+ class MyClass
154
+ include ASIR::Client
155
+ def initialize x
156
+ @x = x
157
+ end
158
+ def method_missing sel, *args
159
+ @x.send(sel, *args)
160
+ end
161
+ end
162
+ # !SLIDE END