cod 0.3.1 → 0.4.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/Gemfile +1 -1
- data/HISTORY.txt +5 -1
- data/README +12 -13
- data/Rakefile +7 -1
- data/examples/{ping.rb → ping_pong/ping.rb} +1 -1
- data/examples/{pong.rb → ping_pong/pong.rb} +1 -1
- data/examples/{presence_client.rb → presence/client.rb} +0 -0
- data/examples/{presence_server.rb → presence/server.rb} +0 -0
- data/examples/queue/README +9 -0
- data/examples/queue/client.rb +31 -0
- data/examples/queue/queue.rb +51 -0
- data/examples/queue/send.rb +9 -0
- data/examples/service.rb +2 -2
- data/examples/tcp.rb +1 -1
- data/lib/cod.rb +47 -82
- data/lib/cod/beanstalk.rb +7 -0
- data/lib/cod/beanstalk/channel.rb +170 -0
- data/lib/cod/beanstalk/serializer.rb +80 -0
- data/lib/cod/beanstalk/service.rb +53 -0
- data/lib/cod/channel.rb +54 -12
- data/lib/cod/pipe.rb +188 -0
- data/lib/cod/select.rb +47 -0
- data/lib/cod/select_group.rb +87 -0
- data/lib/cod/service.rb +55 -42
- data/lib/cod/simple_serializer.rb +19 -0
- data/lib/cod/tcp_client.rb +202 -0
- data/lib/cod/tcp_server.rb +124 -0
- data/lib/cod/work_queue.rb +129 -0
- metadata +31 -45
- data/examples/pubsub/README +0 -12
- data/examples/pubsub/client.rb +0 -13
- data/examples/pubsub/directory.rb +0 -13
- data/examples/service_directory.rb +0 -32
- data/lib/cod/channel/base.rb +0 -185
- data/lib/cod/channel/beanstalk.rb +0 -69
- data/lib/cod/channel/pipe.rb +0 -137
- data/lib/cod/channel/tcp.rb +0 -16
- data/lib/cod/channel/tcpconnection.rb +0 -67
- data/lib/cod/channel/tcpserver.rb +0 -84
- data/lib/cod/client.rb +0 -81
- data/lib/cod/connection/beanstalk.rb +0 -77
- data/lib/cod/directory.rb +0 -98
- data/lib/cod/directory/countdown.rb +0 -31
- data/lib/cod/directory/subscription.rb +0 -59
- data/lib/cod/object_io.rb +0 -6
- data/lib/cod/objectio/connection.rb +0 -106
- data/lib/cod/objectio/reader.rb +0 -98
- data/lib/cod/objectio/serializer.rb +0 -26
- data/lib/cod/objectio/writer.rb +0 -27
- data/lib/cod/topic.rb +0 -95
@@ -0,0 +1,129 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Cod
|
4
|
+
# Describes a queue that stores work items given through #schedule and works
|
5
|
+
# through those items in order if #predicate is true.
|
6
|
+
#
|
7
|
+
# Synopsis:
|
8
|
+
# queue = WorkQueue.new
|
9
|
+
# queue.predicate { true }
|
10
|
+
# queue.schedule {
|
11
|
+
# # some work
|
12
|
+
# }
|
13
|
+
#
|
14
|
+
# # Will try to work through items right now.
|
15
|
+
# queue.try_work
|
16
|
+
#
|
17
|
+
# # Will cleanly shutdown background threads, but not finish work.
|
18
|
+
# queue.shutdown
|
19
|
+
#
|
20
|
+
class WorkQueue # :nodoc:
|
21
|
+
def initialize
|
22
|
+
# NOTE: This is an array that is protected by careful coding, rather
|
23
|
+
# than a mutex. Queue would be right, but Rubys GIL will interfere with
|
24
|
+
# that producing more deadlocks than I would like.
|
25
|
+
@queue = Array.new
|
26
|
+
|
27
|
+
@try_work_exclusive_section = ExclusiveSection.new
|
28
|
+
|
29
|
+
@thread = Thread.start(&method(:thread_main))
|
30
|
+
end
|
31
|
+
|
32
|
+
# The internal thread that is used to work on scheduled items in the
|
33
|
+
# background.
|
34
|
+
attr_reader :thread
|
35
|
+
|
36
|
+
def try_work
|
37
|
+
@try_work_exclusive_section.enter {
|
38
|
+
# NOTE if predicate is nil or not set, no work will be accomplished.
|
39
|
+
# This is the way I need it.
|
40
|
+
while !@queue.empty? && @predicate && @predicate.call
|
41
|
+
wi = @queue.shift
|
42
|
+
wi.call
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
# Before any kind of work is attempted, this predicate must evaluate to
|
48
|
+
# true. It is tested repeatedly.
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
# work_queue.predicate { connection.established? }
|
52
|
+
#
|
53
|
+
def predicate(&predicate)
|
54
|
+
@predicate = predicate
|
55
|
+
end
|
56
|
+
|
57
|
+
# Schedules a piece of work.
|
58
|
+
# Example:
|
59
|
+
# work_queue.schedule { a_piece_of_work }
|
60
|
+
#
|
61
|
+
def schedule(&work)
|
62
|
+
@queue << work
|
63
|
+
end
|
64
|
+
|
65
|
+
# Shuts down the queue properly, without waiting for work to be completed.
|
66
|
+
#
|
67
|
+
def shutdown
|
68
|
+
@shutdown_requested = true
|
69
|
+
@thread.join
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the size of the queue.
|
73
|
+
#
|
74
|
+
def size
|
75
|
+
@queue.size
|
76
|
+
end
|
77
|
+
|
78
|
+
def clear_thread_semaphore
|
79
|
+
@one_turn = false
|
80
|
+
end
|
81
|
+
def thread_semaphore_set?
|
82
|
+
@one_turn
|
83
|
+
end
|
84
|
+
private
|
85
|
+
def thread_main
|
86
|
+
Thread.current.abort_on_exception = true
|
87
|
+
|
88
|
+
loop do
|
89
|
+
sleep 0.01
|
90
|
+
|
91
|
+
try_work
|
92
|
+
|
93
|
+
# Signal the outside world that we've been around this loop once.
|
94
|
+
# See #clear_thread_semaphore and #thread_semaphore_set?
|
95
|
+
@one_turn = true
|
96
|
+
|
97
|
+
return if @shutdown_requested
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# A section of code that is entered only once. Instead of blocking threads
|
103
|
+
# that are waiting to enter, it just returns nil.
|
104
|
+
#
|
105
|
+
class ExclusiveSection # :nodoc:
|
106
|
+
def initialize
|
107
|
+
@mutex = Mutex.new
|
108
|
+
@threads_in_block = 0
|
109
|
+
end
|
110
|
+
|
111
|
+
# If no one is in the block given to #enter currently, this will yield
|
112
|
+
# to the block. If one thread is already executing that block, it will
|
113
|
+
# return nil.
|
114
|
+
#
|
115
|
+
def enter
|
116
|
+
@mutex.synchronize {
|
117
|
+
return if @threads_in_block > 0
|
118
|
+
@threads_in_block += 1 }
|
119
|
+
begin
|
120
|
+
yield
|
121
|
+
ensure
|
122
|
+
fail "Assert fails, #{@threads_in_block} threads in block" \
|
123
|
+
if @threads_in_block != 1
|
124
|
+
@mutex.synchronize {
|
125
|
+
@threads_in_block -= 1 }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cod
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: uuid
|
16
|
-
requirement: &70169583690420 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '2'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *70169583690420
|
25
14
|
- !ruby/object:Gem::Dependency
|
26
15
|
name: rspec
|
27
|
-
requirement: &
|
16
|
+
requirement: &70297088779060 !ruby/object:Gem::Requirement
|
28
17
|
none: false
|
29
18
|
requirements:
|
30
19
|
- - ! '>='
|
@@ -32,10 +21,10 @@ dependencies:
|
|
32
21
|
version: '0'
|
33
22
|
type: :development
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *70297088779060
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: flexmock
|
38
|
-
requirement: &
|
27
|
+
requirement: &70297088777820 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: '0'
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70297088777820
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: sdoc
|
49
|
-
requirement: &
|
38
|
+
requirement: &70297088776720 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,7 +43,7 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70297088776720
|
58
47
|
description:
|
59
48
|
email: kaspar.schiess@absurd.li
|
60
49
|
executables: []
|
@@ -67,37 +56,31 @@ files:
|
|
67
56
|
- LICENSE
|
68
57
|
- Rakefile
|
69
58
|
- README
|
70
|
-
- lib/cod/channel
|
71
|
-
- lib/cod/
|
72
|
-
- lib/cod/
|
73
|
-
- lib/cod/
|
74
|
-
- lib/cod/channel/tcpconnection.rb
|
75
|
-
- lib/cod/channel/tcpserver.rb
|
59
|
+
- lib/cod/beanstalk/channel.rb
|
60
|
+
- lib/cod/beanstalk/serializer.rb
|
61
|
+
- lib/cod/beanstalk/service.rb
|
62
|
+
- lib/cod/beanstalk.rb
|
76
63
|
- lib/cod/channel.rb
|
77
|
-
- lib/cod/
|
78
|
-
- lib/cod/
|
79
|
-
- lib/cod/
|
80
|
-
- lib/cod/directory/subscription.rb
|
81
|
-
- lib/cod/directory.rb
|
82
|
-
- lib/cod/object_io.rb
|
83
|
-
- lib/cod/objectio/connection.rb
|
84
|
-
- lib/cod/objectio/reader.rb
|
85
|
-
- lib/cod/objectio/serializer.rb
|
86
|
-
- lib/cod/objectio/writer.rb
|
64
|
+
- lib/cod/pipe.rb
|
65
|
+
- lib/cod/select.rb
|
66
|
+
- lib/cod/select_group.rb
|
87
67
|
- lib/cod/service.rb
|
88
|
-
- lib/cod/
|
68
|
+
- lib/cod/simple_serializer.rb
|
69
|
+
- lib/cod/tcp_client.rb
|
70
|
+
- lib/cod/tcp_server.rb
|
71
|
+
- lib/cod/work_queue.rb
|
89
72
|
- lib/cod.rb
|
90
73
|
- examples/example_scaffold.rb
|
91
74
|
- examples/master_child.rb
|
92
|
-
- examples/ping.rb
|
93
|
-
- examples/pong.rb
|
94
|
-
- examples/
|
95
|
-
- examples/
|
96
|
-
- examples/
|
97
|
-
- examples/
|
98
|
-
- examples/
|
75
|
+
- examples/ping_pong/ping.rb
|
76
|
+
- examples/ping_pong/pong.rb
|
77
|
+
- examples/presence/client.rb
|
78
|
+
- examples/presence/server.rb
|
79
|
+
- examples/queue/client.rb
|
80
|
+
- examples/queue/queue.rb
|
81
|
+
- examples/queue/README
|
82
|
+
- examples/queue/send.rb
|
99
83
|
- examples/service.rb
|
100
|
-
- examples/service_directory.rb
|
101
84
|
- examples/tcp.rb
|
102
85
|
homepage: http://kschiess.github.com/cod
|
103
86
|
licenses: []
|
@@ -113,6 +96,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
96
|
- - ! '>='
|
114
97
|
- !ruby/object:Gem::Version
|
115
98
|
version: '0'
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
hash: -3574736004851783821
|
116
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
103
|
none: false
|
118
104
|
requirements:
|
@@ -121,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
107
|
version: '0'
|
122
108
|
requirements: []
|
123
109
|
rubyforge_project:
|
124
|
-
rubygems_version: 1.8.
|
110
|
+
rubygems_version: 1.8.10
|
125
111
|
signing_key:
|
126
112
|
specification_version: 3
|
127
113
|
summary: Really simple IPC.
|
data/examples/pubsub/README
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
|
2
|
-
This is an example of PUB/SUB style messaging. You should run one directory
|
3
|
-
and any number of clients. All clients should receive timestamps from the directory, once every second.
|
4
|
-
|
5
|
-
Experiments that can be made using this setup:
|
6
|
-
|
7
|
-
1) Disconnect a client, restart it. It should start receiving updates
|
8
|
-
immediately.
|
9
|
-
|
10
|
-
2) Disconnect the directory, restart it. It should start redistributing
|
11
|
-
updates to all clients within 5 seconds.
|
12
|
-
|
data/examples/pubsub/client.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
-
require 'cod'
|
3
|
-
|
4
|
-
channels = Struct.new(:directory, :answers).new(
|
5
|
-
Cod.beanstalk('localhost:11300', 'directory'),
|
6
|
-
Cod.beanstalk('localhost:11300', 'directory.'+Cod.uuid))
|
7
|
-
|
8
|
-
topic = Cod::Topic.new('', channels.directory, channels.answers, :renew => 5)
|
9
|
-
|
10
|
-
loop do
|
11
|
-
puts topic.get
|
12
|
-
end
|
13
|
-
|
@@ -1,13 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
-
require 'cod'
|
3
|
-
|
4
|
-
channels = Struct.new(:directory).new(
|
5
|
-
Cod.beanstalk('localhost:11300', 'directory'))
|
6
|
-
|
7
|
-
directory = Cod::Directory.new(channels.directory)
|
8
|
-
|
9
|
-
loop do
|
10
|
-
directory.publish '', Time.now
|
11
|
-
sleep 1
|
12
|
-
end
|
13
|
-
|
@@ -1,32 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
2
|
-
require 'cod'
|
3
|
-
|
4
|
-
announce = Cod.pipe
|
5
|
-
directory = Cod::Directory.new(announce)
|
6
|
-
|
7
|
-
pipes = []
|
8
|
-
pids = ['foo.bar', /^foo\..+/].map { |match_expr|
|
9
|
-
# Creates a communication channel that both the parent and the child know
|
10
|
-
# about. After the fork, they will own unique ends to that channel.
|
11
|
-
pipes << pipe = Cod.pipe # store in pipes as well to prevent GC
|
12
|
-
|
13
|
-
# Create a child that will receive messages that match match_expr.
|
14
|
-
fork do
|
15
|
-
puts "Spawned child: #{Process.pid}"
|
16
|
-
topic = Cod::Topic.new(match_expr, announce, pipe)
|
17
|
-
|
18
|
-
sleep 0.1
|
19
|
-
loop do
|
20
|
-
message = topic.get
|
21
|
-
puts "#{Process.pid}: received #{message.inspect}."
|
22
|
-
|
23
|
-
break if message == :shutdown
|
24
|
-
end
|
25
|
-
end }
|
26
|
-
|
27
|
-
directory.publish 'foo.bar', 'Hi everyone!' # to both childs
|
28
|
-
directory.publish 'foo.baz', 'Hi you!' # only second child matches this
|
29
|
-
directory.publish 'no.one', 'echo?' # no one matches this
|
30
|
-
|
31
|
-
directory.publish 'foo.bar', :shutdown # shutdown children in orderly fashion
|
32
|
-
Process.waitall
|
data/lib/cod/channel/base.rb
DELETED
@@ -1,185 +0,0 @@
|
|
1
|
-
|
2
|
-
module Cod
|
3
|
-
# Channels are the communication primitives you've always wanted (secretly).
|
4
|
-
# They are simple to use, abstract most of the OS away and allow direct
|
5
|
-
# communication using language objects, not just strings. (Although you can
|
6
|
-
# fall back to just strings if you want to)
|
7
|
-
#
|
8
|
-
# == Construction
|
9
|
-
#
|
10
|
-
# The simplest way to obtain a new channel is through the Module Cod. It
|
11
|
-
# provides the following channel types:
|
12
|
-
#
|
13
|
-
# Cod.beanstalk(url, name) :: connects to beanstalkd daemon
|
14
|
-
# Cod.pipe :: abstracts IO.pipe
|
15
|
-
# Cod.tcp(url) :: connects to a tcp socket somewhere
|
16
|
-
# Cod.tcpserver(url) :: the counterpart to Cod.tcp
|
17
|
-
#
|
18
|
-
# Please refer to the documentation of these methods for more information.
|
19
|
-
#
|
20
|
-
# == Basic Interaction
|
21
|
-
#
|
22
|
-
# You can #put messages (Ruby objects) into a channel on one side:
|
23
|
-
#
|
24
|
-
# channel.put("some message")
|
25
|
-
#
|
26
|
-
# and #get messages on the other side:
|
27
|
-
#
|
28
|
-
# channel.get # => "some message"
|
29
|
-
#
|
30
|
-
# == Querying
|
31
|
-
#
|
32
|
-
# Are there messages waiting to be read from the channel? Use #waiting?:
|
33
|
-
#
|
34
|
-
# channel.waiting? # => true or false
|
35
|
-
#
|
36
|
-
# == Cleaning up
|
37
|
-
#
|
38
|
-
# Be sure to #close the channel once you're done with it.
|
39
|
-
#
|
40
|
-
# channel.close
|
41
|
-
#
|
42
|
-
class Channel::Base
|
43
|
-
def initialize(reader, writer)
|
44
|
-
@reader = reader
|
45
|
-
@writer = writer
|
46
|
-
end
|
47
|
-
|
48
|
-
# Writes a Ruby object (the 'message') to the channel. This object will
|
49
|
-
# be queued in the channel and become available for #get in a FIFO manner.
|
50
|
-
#
|
51
|
-
# Issuing a #put may also close the channel instance for subsequent #get's.
|
52
|
-
#
|
53
|
-
# Example:
|
54
|
-
# chan.put 'test'
|
55
|
-
# chan.put true
|
56
|
-
# chan.put :symbol
|
57
|
-
#
|
58
|
-
def put(message)
|
59
|
-
# TODO Errno::EPIPE raised after a while when the receiver goes away.
|
60
|
-
@writer.put(message)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Reads a Ruby object (a message) from the channel. Some channels may not
|
64
|
-
# allow reading after you've written to it once. Options that work:
|
65
|
-
#
|
66
|
-
# <code>:timeout</code> :: Time to wait before throwing Cod::Channel::TimeoutError.
|
67
|
-
#
|
68
|
-
def get(opts={})
|
69
|
-
@reader.get(opts)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Returns true if there are messages waiting in the channel.
|
73
|
-
#
|
74
|
-
def waiting?
|
75
|
-
# TODO EOFError is thrown when the other end has gone away
|
76
|
-
@reader.waiting?
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns true if the channel is connected, and false if all hope must be
|
80
|
-
# given up of reconnecting this channel.
|
81
|
-
#
|
82
|
-
def connected?
|
83
|
-
not_implemented
|
84
|
-
end
|
85
|
-
|
86
|
-
# Closes reader and writer.
|
87
|
-
#
|
88
|
-
def close
|
89
|
-
@reader.close if @reader
|
90
|
-
@writer.close if @writer
|
91
|
-
|
92
|
-
@reader = @writer = nil
|
93
|
-
end
|
94
|
-
|
95
|
-
# Returns the Identifier class below the current channel class. This is
|
96
|
-
# a helper function that should only be used by subclasses.
|
97
|
-
#
|
98
|
-
def identifier_class # :nodoc:
|
99
|
-
self.class.const_get(:Identifier)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Something to put into the data stream that is transmitted through a
|
103
|
-
# channel that allows reconstitution of the channel at the other end.
|
104
|
-
# The invariant is this:
|
105
|
-
#
|
106
|
-
# # channel1 and channel2 are abstract channels that illustrate my
|
107
|
-
# # meaning
|
108
|
-
# channel1.put channel2
|
109
|
-
# channel2a = channel1.get
|
110
|
-
# channel2a.put 'foo'
|
111
|
-
# channel2.get # => 'foo'
|
112
|
-
#
|
113
|
-
# Note that this should also work if channel1 and channel2 are the same.
|
114
|
-
#
|
115
|
-
def identifier # :nodoc:
|
116
|
-
identifier_class.new(self)
|
117
|
-
end
|
118
|
-
|
119
|
-
# ------------------------------------------------------------ marshalling
|
120
|
-
|
121
|
-
# Makes sure that we don't marshal this object, but the memento object
|
122
|
-
# returned by identifier.
|
123
|
-
#
|
124
|
-
def _dump(d) # :nodoc:
|
125
|
-
wire_data = to_wire_data
|
126
|
-
Marshal.dump(wire_data)
|
127
|
-
end
|
128
|
-
|
129
|
-
# Loads the object from string. This doesn't always return the same kind
|
130
|
-
# of object that was serialized.
|
131
|
-
#
|
132
|
-
def self._load(string) # :nodoc:
|
133
|
-
wire_data = Marshal.load(string)
|
134
|
-
from_wire_data(wire_data)
|
135
|
-
end
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
# Returns the objects that need to be transmitted in order to reconstruct
|
140
|
-
# this object after transmission through the wire.
|
141
|
-
#
|
142
|
-
# If you're using a serialisation method other than the Ruby built in
|
143
|
-
# one, use this to obtain something in lieu of a channel that can be sent
|
144
|
-
# through the wire and reinterpreted at the other end.
|
145
|
-
#
|
146
|
-
# Example:
|
147
|
-
#
|
148
|
-
# # this should work:
|
149
|
-
# obj = channel.to_wire_data
|
150
|
-
# channel_equiv = Cod::Channel::Base.from_wire_data(obj)
|
151
|
-
#
|
152
|
-
def to_wire_data
|
153
|
-
identifier
|
154
|
-
end
|
155
|
-
|
156
|
-
# Using an object previously returned by #to_wire_data, reconstitute the
|
157
|
-
# original channel or something that is alike it. What you send to this
|
158
|
-
# second channel (#put) you should be able to #get from this copy returned
|
159
|
-
# here.
|
160
|
-
#
|
161
|
-
def self.from_wire_data(obj)
|
162
|
-
obj.resolve
|
163
|
-
end
|
164
|
-
|
165
|
-
# ---------------------------------------------------------- error raising
|
166
|
-
|
167
|
-
def direction_error(msg)
|
168
|
-
raise Cod::Channel::DirectionError, msg
|
169
|
-
end
|
170
|
-
|
171
|
-
def communication_error(msg)
|
172
|
-
raise Cod::Channel::CommunicationError, msg
|
173
|
-
end
|
174
|
-
|
175
|
-
def not_implemented
|
176
|
-
trace = caller.reject {|l| l =~ %r{#{Regexp.escape(__FILE__)}}} # blatantly stolen from dependencies.rb in activesupport
|
177
|
-
exception = NotImplementedError.new(
|
178
|
-
"You called a method in Cod::Channel::Base. Missing implementation in "+
|
179
|
-
"the subclass #{self.class.name}!")
|
180
|
-
exception.set_backtrace trace
|
181
|
-
|
182
|
-
raise exception
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|