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.
- data/.gitignore +11 -0
- data/Gemfile +16 -0
- data/README.textile +50 -0
- data/Rakefile +83 -0
- data/VERSION +1 -0
- data/asir.gemspec +36 -0
- data/asir.riterate.yml +114 -0
- data/bin/asir +6 -0
- data/doc/Rakefile +8 -0
- data/doc/asir-sequence.pic +84 -0
- data/doc/asir-sequence.svg +1559 -0
- data/doc/sequence.pic +430 -0
- data/example/asir_control.sh +24 -0
- data/example/asir_control_client_http.rb +14 -0
- data/example/asir_control_client_zmq.rb +15 -0
- data/example/config/asir_config.rb +63 -0
- data/example/delayed_service.rb +15 -0
- data/example/ex01.rb +12 -0
- data/example/ex02.rb +12 -0
- data/example/ex03.rb +19 -0
- data/example/ex04.rb +33 -0
- data/example/ex05.rb +16 -0
- data/example/ex06.rb +26 -0
- data/example/ex07.rb +28 -0
- data/example/ex08.rb +30 -0
- data/example/ex09.rb +25 -0
- data/example/ex10.rb +24 -0
- data/example/ex11.rb +48 -0
- data/example/ex12.rb +34 -0
- data/example/ex13.rb +35 -0
- data/example/ex14.rb +30 -0
- data/example/ex15.rb +13 -0
- data/example/ex16.rb +33 -0
- data/example/ex17.rb +41 -0
- data/example/ex18.rb +62 -0
- data/example/ex19.rb +32 -0
- data/example/ex20.rb +28 -0
- data/example/ex21.rb +28 -0
- data/example/ex22.rb +15 -0
- data/example/ex23.rb +20 -0
- data/example/ex24.rb +35 -0
- data/example/example_helper.rb +51 -0
- data/example/sample_service.rb +162 -0
- data/example/unsafe_service.rb +12 -0
- data/hack_night/README.txt +18 -0
- data/hack_night/exercise/prob-1.rb +18 -0
- data/hack_night/exercise/prob-2.rb +21 -0
- data/hack_night/exercise/prob-3.rb +16 -0
- data/hack_night/exercise/prob-4.rb +36 -0
- data/hack_night/exercise/prob-5.rb +36 -0
- data/hack_night/exercise/prob-6.rb +95 -0
- data/hack_night/exercise/prob-7.rb +34 -0
- data/hack_night/solution/math_service.rb +11 -0
- data/hack_night/solution/prob-1.rb +12 -0
- data/hack_night/solution/prob-2.rb +15 -0
- data/hack_night/solution/prob-3.rb +17 -0
- data/hack_night/solution/prob-4.rb +37 -0
- data/hack_night/solution/prob-5.rb +21 -0
- data/hack_night/solution/prob-6.rb +33 -0
- data/hack_night/solution/prob-7.rb +36 -0
- data/lab/phony_proc.rb +31 -0
- data/lib/asir.rb +253 -0
- data/lib/asir/additional_data.rb +25 -0
- data/lib/asir/channel.rb +130 -0
- data/lib/asir/client.rb +111 -0
- data/lib/asir/code_block.rb +57 -0
- data/lib/asir/code_more.rb +50 -0
- data/lib/asir/coder.rb +26 -0
- data/lib/asir/coder/base64.rb +19 -0
- data/lib/asir/coder/chain.rb +30 -0
- data/lib/asir/coder/identity.rb +23 -0
- data/lib/asir/coder/json.rb +30 -0
- data/lib/asir/coder/marshal.rb +17 -0
- data/lib/asir/coder/null.rb +23 -0
- data/lib/asir/coder/proc.rb +22 -0
- data/lib/asir/coder/sign.rb +48 -0
- data/lib/asir/coder/xml.rb +213 -0
- data/lib/asir/coder/yaml.rb +33 -0
- data/lib/asir/coder/zlib.rb +21 -0
- data/lib/asir/configuration.rb +32 -0
- data/lib/asir/error.rb +34 -0
- data/lib/asir/identity.rb +36 -0
- data/lib/asir/initialization.rb +23 -0
- data/lib/asir/log.rb +82 -0
- data/lib/asir/main.rb +396 -0
- data/lib/asir/message.rb +31 -0
- data/lib/asir/message/delay.rb +35 -0
- data/lib/asir/object_resolving.rb +15 -0
- data/lib/asir/result.rb +39 -0
- data/lib/asir/retry_behavior.rb +54 -0
- data/lib/asir/transport.rb +241 -0
- data/lib/asir/transport/beanstalk.rb +217 -0
- data/lib/asir/transport/broadcast.rb +34 -0
- data/lib/asir/transport/buffer.rb +115 -0
- data/lib/asir/transport/composite.rb +19 -0
- data/lib/asir/transport/connection_oriented.rb +180 -0
- data/lib/asir/transport/delay.rb +38 -0
- data/lib/asir/transport/delegation.rb +53 -0
- data/lib/asir/transport/fallback.rb +36 -0
- data/lib/asir/transport/file.rb +88 -0
- data/lib/asir/transport/http.rb +54 -0
- data/lib/asir/transport/local.rb +21 -0
- data/lib/asir/transport/null.rb +14 -0
- data/lib/asir/transport/payload_io.rb +52 -0
- data/lib/asir/transport/rack.rb +73 -0
- data/lib/asir/transport/retry.rb +41 -0
- data/lib/asir/transport/stream.rb +35 -0
- data/lib/asir/transport/subprocess.rb +30 -0
- data/lib/asir/transport/tcp_socket.rb +34 -0
- data/lib/asir/transport/webrick.rb +50 -0
- data/lib/asir/transport/zmq.rb +110 -0
- data/lib/asir/uuid.rb +32 -0
- data/lib/asir/version.rb +3 -0
- data/spec/const_get_speed_spec.rb +33 -0
- data/spec/debug_helper.rb +20 -0
- data/spec/example_spec.rb +88 -0
- data/spec/json_spec.rb +128 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/xml_spec.rb +144 -0
- data/stylesheets/slides.css +105 -0
- metadata +173 -0
data/example/ex14.rb
ADDED
|
@@ -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
|
+
|
data/example/ex15.rb
ADDED
|
@@ -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
|
data/example/ex16.rb
ADDED
|
@@ -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
|
+
|
data/example/ex17.rb
ADDED
|
@@ -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
|
+
|
data/example/ex18.rb
ADDED
|
@@ -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
|
data/example/ex19.rb
ADDED
|
@@ -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
|
data/example/ex20.rb
ADDED
|
@@ -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
|
data/example/ex21.rb
ADDED
|
@@ -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
|
data/example/ex22.rb
ADDED
|
@@ -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]
|
data/example/ex23.rb
ADDED
|
@@ -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
|
+
|
data/example/ex24.rb
ADDED
|
@@ -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
|