asir 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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