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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'asir/transport/stream'
|
|
2
|
+
require 'asir/transport/payload_io'
|
|
3
|
+
|
|
4
|
+
module ASIR
|
|
5
|
+
class Transport
|
|
6
|
+
# !SLIDE
|
|
7
|
+
# File Transport
|
|
8
|
+
#
|
|
9
|
+
# Send Message one-way to a file.
|
|
10
|
+
# Can be used as a log or named pipe service.
|
|
11
|
+
class File < Stream
|
|
12
|
+
include PayloadIO # _write, _read
|
|
13
|
+
attr_accessor :file, :mode, :perms, :stream
|
|
14
|
+
|
|
15
|
+
def initialize opts = nil; @one_way = true; super; end
|
|
16
|
+
|
|
17
|
+
# Writes a Message payload String.
|
|
18
|
+
def _send_message message, message_payload
|
|
19
|
+
_write message_payload, stream
|
|
20
|
+
ensure
|
|
21
|
+
close if ::File.pipe?(file)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns a Message payload String.
|
|
25
|
+
def _receive_message stream, additional_data
|
|
26
|
+
[ _read(stream), nil ]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# one-way; no Result.
|
|
30
|
+
def _send_result message, result, result_payload, stream, message_state
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# one-way; no Result.
|
|
35
|
+
def _receive_result message, opaque_result
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# !SLIDE
|
|
40
|
+
# File Transport Support
|
|
41
|
+
|
|
42
|
+
def stream
|
|
43
|
+
@stream ||=
|
|
44
|
+
begin
|
|
45
|
+
stream = ::File.open(file, mode || "w+")
|
|
46
|
+
::File.chmod(perms, file) rescue nil if @perms
|
|
47
|
+
after_connect!(stream) if respond_to?(:after_connect!)
|
|
48
|
+
stream
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# !SLIDE
|
|
53
|
+
# Process (receive) messages from a file.
|
|
54
|
+
|
|
55
|
+
def serve_file!
|
|
56
|
+
::File.open(file, "r") do | stream |
|
|
57
|
+
@running = true
|
|
58
|
+
serve_stream! stream, nil # One-way: no result stream.
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# !SLIDE
|
|
63
|
+
# Named Pipe Server
|
|
64
|
+
|
|
65
|
+
def prepare_pipe_server!
|
|
66
|
+
# _log [ :prepare_pipe_server!, file ]
|
|
67
|
+
unless ::File.exist? file
|
|
68
|
+
system(cmd = "mkfifo #{file.inspect}") or raise "cannot run #{cmd.inspect}"
|
|
69
|
+
::File.chmod(perms, file) rescue nil if perms
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def run_pipe_server!
|
|
74
|
+
# _log [ :run_pipe_server!, file ]
|
|
75
|
+
with_server_signals! do
|
|
76
|
+
@running = true
|
|
77
|
+
while @running
|
|
78
|
+
serve_file!
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# !SLIDE END
|
|
84
|
+
end
|
|
85
|
+
# !SLIDE END
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'asir'
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
gem 'httpclient'
|
|
5
|
+
require 'httpclient'
|
|
6
|
+
require 'uri'
|
|
7
|
+
|
|
8
|
+
module ASIR
|
|
9
|
+
class Transport
|
|
10
|
+
# !SLIDE
|
|
11
|
+
# HTTP Transport
|
|
12
|
+
#
|
|
13
|
+
# Using HTTPClient.
|
|
14
|
+
class HTTP < self
|
|
15
|
+
attr_accessor :uri, :server, :debug
|
|
16
|
+
|
|
17
|
+
# Client-side: HTTPClient
|
|
18
|
+
|
|
19
|
+
def client
|
|
20
|
+
@client ||=
|
|
21
|
+
Channel.new(:on_connect =>
|
|
22
|
+
lambda { | channel | ::HTTPClient.new })
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def close
|
|
26
|
+
@client.close if @client
|
|
27
|
+
ensure
|
|
28
|
+
@client = nil unless Channel === @client
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Send the Message payload String using HTTP POST.
|
|
32
|
+
# Returns the HTTPClient::Request response object.
|
|
33
|
+
def _send_message message, message_payload
|
|
34
|
+
client.with_stream! do | client |
|
|
35
|
+
client.post(uri, message_payload)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Recieve the Result payload String from the opaque
|
|
40
|
+
# HTTPClient::Request response object returned from #_send_message.
|
|
41
|
+
def _receive_result message, http_result_message
|
|
42
|
+
# $stderr.puts " ### http_result_message.content.encoding = #{http_result_message.content.encoding.inspect}" rescue nil
|
|
43
|
+
# $stderr.puts " ### http_result_message.content = #{http_result_message.content.inspect}" rescue nil
|
|
44
|
+
http_result_message.content.to_s
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
CONTENT_TYPE = 'Content-Type'.freeze
|
|
48
|
+
APPLICATION_BINARY = 'application/binary'.freeze
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
# !SLIDE END
|
|
52
|
+
end # class
|
|
53
|
+
end # module
|
|
54
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module ASIR
|
|
2
|
+
class Transport
|
|
3
|
+
# !SLIDE
|
|
4
|
+
# Local Transport
|
|
5
|
+
#
|
|
6
|
+
# Send Message to same process.
|
|
7
|
+
# Requires Identity Coder.
|
|
8
|
+
class Local < self
|
|
9
|
+
# Returns Result object after invoking Message.
|
|
10
|
+
def _send_message message, message_payload
|
|
11
|
+
invoke_message!(message)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns Result object from #send_message.
|
|
15
|
+
def _receive_result message, opaque_result
|
|
16
|
+
opaque_result
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
# !SLIDE END
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module ASIR
|
|
2
|
+
class Transport
|
|
3
|
+
# !SLIDE
|
|
4
|
+
# Payload IO for Transport
|
|
5
|
+
#
|
|
6
|
+
# Framing
|
|
7
|
+
# * Line containing the number of bytes in the payload.
|
|
8
|
+
# * The payload bytes.
|
|
9
|
+
# * Blank line.
|
|
10
|
+
module PayloadIO
|
|
11
|
+
class UnexpectedResponse < Error; end
|
|
12
|
+
|
|
13
|
+
NEWLINE = "\n"
|
|
14
|
+
|
|
15
|
+
def _write payload, stream
|
|
16
|
+
stream.puts payload.size
|
|
17
|
+
stream.write payload
|
|
18
|
+
stream.write NEWLINE
|
|
19
|
+
stream.flush
|
|
20
|
+
stream
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def _read stream
|
|
24
|
+
size = stream.readline.chomp.to_i
|
|
25
|
+
payload = stream.read(size)
|
|
26
|
+
stream.readline
|
|
27
|
+
payload
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _read_line_and_expect! stream, regexp
|
|
31
|
+
line = stream.readline
|
|
32
|
+
unless match = regexp.match(line)
|
|
33
|
+
_log { "_read_line_and_expect! #{stream} #{regexp.inspect} !~ #{line.inspect}" }
|
|
34
|
+
raise UnexpectedResponse, "expected #{regexp.inspect}, received #{line.inspect}"
|
|
35
|
+
end
|
|
36
|
+
match
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# !SLIDE pause
|
|
40
|
+
def close
|
|
41
|
+
if @stream
|
|
42
|
+
_before_close! stream if respond_to?(:_before_close!)
|
|
43
|
+
@stream.close
|
|
44
|
+
end
|
|
45
|
+
ensure
|
|
46
|
+
@stream = nil unless Channel === @stream
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# !SLIDE resume
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'asir/transport/http'
|
|
2
|
+
require 'rack'
|
|
3
|
+
|
|
4
|
+
module ASIR
|
|
5
|
+
class Transport
|
|
6
|
+
# !SLIDE
|
|
7
|
+
# Rack Transport
|
|
8
|
+
class Rack < HTTP
|
|
9
|
+
# Receive the Message payload String from the Rack::Request object.
|
|
10
|
+
# Returns the [ Rack::Request, Rack::Response ] as the message_state.
|
|
11
|
+
def _receive_message rack_req_res, additional_data
|
|
12
|
+
body = rack_req_res.first.body.read
|
|
13
|
+
[ body, rack_req_res ]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Send the Result payload String in the Rack::Response object as application/binary.
|
|
17
|
+
def _send_result message, result, result_payload, rack_rq_rs, message_state
|
|
18
|
+
rack_response = rack_rq_rs[1]
|
|
19
|
+
rack_response[CONTENT_TYPE] = APPLICATION_BINARY
|
|
20
|
+
rack_response.write result_payload
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Constructs a Rackable App from this Transport.
|
|
24
|
+
def rack_app &blk
|
|
25
|
+
App.new(self, &blk)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Rack Transport Application.
|
|
29
|
+
class App
|
|
30
|
+
def initialize transport = nil, &blk
|
|
31
|
+
@app = transport
|
|
32
|
+
instance_eval &blk if blk
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def call env
|
|
36
|
+
@app.call(env)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Rack application handler.
|
|
41
|
+
def call(env)
|
|
42
|
+
rq = ::Rack::Request.new(env)
|
|
43
|
+
rs = ::Rack::Response.new
|
|
44
|
+
rack_rq_rs = [ rq, rs ]
|
|
45
|
+
serve_message! rack_rq_rs, rack_rq_rs
|
|
46
|
+
rs.finish # => [ status, header, rbody ]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
###############################
|
|
50
|
+
# Dummy server.
|
|
51
|
+
|
|
52
|
+
def prepare_server! opts = { }
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# WEBrick under Rack.
|
|
57
|
+
def run_server!
|
|
58
|
+
#require 'rack/handler'
|
|
59
|
+
u = URI.parse(uri); port = u.port # <= REFACTOR
|
|
60
|
+
::Rack::Handler::WEBrick.run \
|
|
61
|
+
::Rack::ShowExceptions.new(::Rack::Lint.new(self.rack_app)),
|
|
62
|
+
:Port => port
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def stop_server!
|
|
67
|
+
# NOT IMPLEMENTED
|
|
68
|
+
self
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
# !SLIDE END
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'asir/transport/delegation'
|
|
2
|
+
require 'asir/retry_behavior'
|
|
3
|
+
|
|
4
|
+
module ASIR
|
|
5
|
+
class Transport
|
|
6
|
+
# !SLIDE
|
|
7
|
+
# Retry Transport
|
|
8
|
+
class Retry < self
|
|
9
|
+
include Delegation, RetryBehavior
|
|
10
|
+
|
|
11
|
+
# The transport to delegate to.
|
|
12
|
+
attr_accessor :transport
|
|
13
|
+
# Proc to call(transport, message) before retry.
|
|
14
|
+
attr_accessor :before_retry
|
|
15
|
+
|
|
16
|
+
def _send_message message, message_payload
|
|
17
|
+
first_exception = nil
|
|
18
|
+
with_retry do | action, data |
|
|
19
|
+
case action
|
|
20
|
+
when :try
|
|
21
|
+
transport.send_message(message)
|
|
22
|
+
when :rescue #, exc
|
|
23
|
+
first_exception ||= data
|
|
24
|
+
_handle_send_message_exception! transport, message, data
|
|
25
|
+
when :retry #, exc
|
|
26
|
+
before_retry.call(self, message) if before_retry
|
|
27
|
+
when :failed
|
|
28
|
+
@on_failed_message.call(self, message) if @on_failed_message
|
|
29
|
+
if first_exception && @reraise_first_exception
|
|
30
|
+
$! = first_exception
|
|
31
|
+
raise
|
|
32
|
+
end
|
|
33
|
+
nil # fallback to raise RetryError
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
# !SLIDE END
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module ASIR
|
|
2
|
+
class Transport
|
|
3
|
+
# !SLIDE
|
|
4
|
+
# Stream Transport
|
|
5
|
+
#
|
|
6
|
+
# Base class handles Messages on a stream.
|
|
7
|
+
# Stream Transports require a Coder that encodes to and from String payloads.
|
|
8
|
+
class Stream < self
|
|
9
|
+
|
|
10
|
+
# !SLIDE
|
|
11
|
+
# Serve all Messages from a stream.
|
|
12
|
+
def serve_stream! in_stream, out_stream
|
|
13
|
+
with_server_signals! do
|
|
14
|
+
while @running && ! in_stream.eof?
|
|
15
|
+
begin
|
|
16
|
+
serve_stream_message! in_stream, out_stream
|
|
17
|
+
rescue Error::Terminate => err
|
|
18
|
+
@running = false
|
|
19
|
+
_log [ :serve_stream_terminate, err ]
|
|
20
|
+
rescue ::Exception => err
|
|
21
|
+
_log [ :serve_stream_error, err ]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# !SLIDE
|
|
28
|
+
# Serve a Message from a stream.
|
|
29
|
+
def serve_stream_message! in_stream, out_stream
|
|
30
|
+
serve_message! in_stream, out_stream
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
# !SLIDE END
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'asir/transport/local'
|
|
2
|
+
|
|
3
|
+
module ASIR
|
|
4
|
+
class Transport
|
|
5
|
+
# !SLIDE
|
|
6
|
+
# Subprocess Transport
|
|
7
|
+
#
|
|
8
|
+
# Send one-way Message to a forked subprocess.
|
|
9
|
+
class Subprocess < Local
|
|
10
|
+
def initialize *args
|
|
11
|
+
@one_way = true; super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def _send_message message, message_payload
|
|
15
|
+
Process.fork do
|
|
16
|
+
send_result(super, nil, nil)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# one-way; no Result
|
|
21
|
+
def _receive_result message, opaque_result
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# one-way; no Result
|
|
25
|
+
def _send_result message, result, result_payload, stream, message_state
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
# !SLIDE END
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'asir/transport/connection_oriented'
|
|
2
|
+
require 'socket'
|
|
3
|
+
|
|
4
|
+
module ASIR
|
|
5
|
+
class Transport
|
|
6
|
+
# !SLIDE
|
|
7
|
+
# TCP Socket Transport
|
|
8
|
+
class TcpSocket < ConnectionOriented
|
|
9
|
+
# !SLIDE
|
|
10
|
+
# TCP Socket Client
|
|
11
|
+
def _client_connect!
|
|
12
|
+
sock = TCPSocket.open(address, port)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# !SLIDE
|
|
16
|
+
# TCP Socket Server
|
|
17
|
+
def _server!
|
|
18
|
+
@server = TCPServer.open(port)
|
|
19
|
+
@server.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, false)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def _server_accept_connection! server
|
|
23
|
+
server.accept
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def _server_close_connection! stream
|
|
27
|
+
stream.close rescue nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
# !SLIDE END
|
|
31
|
+
end # class
|
|
32
|
+
end # module
|
|
33
|
+
|
|
34
|
+
|