motel 0.3 → 0.3.1
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/Rakefile +5 -3
- data/bin/motel-client +211 -0
- data/bin/motel-rage-client +80 -0
- data/bin/{server/main.rb → motel-server} +0 -3
- data/conf/motel-schema.xml +30 -5
- data/lib/motel.rb +3 -1
- data/lib/motel/callbacks.rb +139 -0
- data/lib/motel/location.rb +23 -4
- data/lib/motel/movement_strategies/elliptical.rb +1 -0
- data/lib/motel/movement_strategies/linear.rb +1 -0
- data/lib/motel/movement_strategy.rb +4 -3
- data/lib/motel/runner.rb +136 -38
- data/lib/motel/simrpc_adapter.rb +190 -0
- data/spec/callbacks_spec.rb +156 -0
- data/spec/dsl_spec.rb +5 -5
- data/spec/location_spec.rb +15 -10
- data/spec/runner_spec.rb +24 -10
- data/spec/simrpc_spec.rb +142 -21
- data/spec/spec_helper.rb +1 -0
- metadata +48 -13
- data/bin/clients/simple/main.rb +0 -131
- data/lib/motel/simrpc.rb +0 -131
- data/lib/motel/thread_pool.rb +0 -51
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Mohammed Morsi
|
@@ -9,21 +15,36 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-09-05 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 27
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
version: 1.3.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
16
37
|
description: Motel is a library to track and move the locations of objects in a 3D environment.
|
17
38
|
email: movitto@yahoo.com
|
18
|
-
executables:
|
19
|
-
|
39
|
+
executables:
|
40
|
+
- motel-server
|
41
|
+
- motel-client
|
42
|
+
- motel-rage-client
|
20
43
|
extensions: []
|
21
44
|
|
22
45
|
extra_rdoc_files: []
|
23
46
|
|
24
47
|
files:
|
25
|
-
- bin/server/main.rb
|
26
|
-
- bin/clients/simple/main.rb
|
27
48
|
- conf/motel-schema.xml
|
28
49
|
- lib/motel/movement_strategies/elliptical.rb
|
29
50
|
- lib/motel/movement_strategies/stopped.rb
|
@@ -33,10 +54,10 @@ files:
|
|
33
54
|
- lib/motel/location.rb
|
34
55
|
- lib/motel/common.rb
|
35
56
|
- lib/motel/semaphore.rb
|
36
|
-
- lib/motel/
|
57
|
+
- lib/motel/simrpc_adapter.rb
|
37
58
|
- lib/motel/runner.rb
|
59
|
+
- lib/motel/callbacks.rb
|
38
60
|
- lib/motel/exceptions.rb
|
39
|
-
- lib/motel/simrpc.rb
|
40
61
|
- lib/motel.rb
|
41
62
|
- COPYING
|
42
63
|
- LICENSE
|
@@ -48,10 +69,14 @@ files:
|
|
48
69
|
- spec/common_spec.rb
|
49
70
|
- spec/spec_helper.rb
|
50
71
|
- spec/movement_strategy_spec.rb
|
72
|
+
- spec/callbacks_spec.rb
|
51
73
|
- spec/location_spec.rb
|
52
74
|
- spec/simrpc_spec.rb
|
53
75
|
- spec/runner_spec.rb
|
54
76
|
- spec/dsl_spec.rb
|
77
|
+
- bin/motel-server
|
78
|
+
- bin/motel-client
|
79
|
+
- bin/motel-rage-client
|
55
80
|
has_rdoc: true
|
56
81
|
homepage: http://morsi.org/projects/motel
|
57
82
|
licenses: []
|
@@ -62,21 +87,31 @@ rdoc_options: []
|
|
62
87
|
require_paths:
|
63
88
|
- lib
|
64
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
65
91
|
requirements:
|
66
92
|
- - ">="
|
67
93
|
- !ruby/object:Gem::Version
|
94
|
+
hash: 53
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 8
|
98
|
+
- 1
|
68
99
|
version: 1.8.1
|
69
|
-
version:
|
70
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
71
102
|
requirements:
|
72
103
|
- - ">="
|
73
104
|
- !ruby/object:Gem::Version
|
105
|
+
hash: 29
|
106
|
+
segments:
|
107
|
+
- 1
|
108
|
+
- 3
|
109
|
+
- 3
|
74
110
|
version: 1.3.3
|
75
|
-
version:
|
76
111
|
requirements: []
|
77
112
|
|
78
113
|
rubyforge_project:
|
79
|
-
rubygems_version: 1.3.
|
114
|
+
rubygems_version: 1.3.7
|
80
115
|
signing_key:
|
81
116
|
specification_version: 3
|
82
117
|
summary: Motel is a library to track and move the locations of objects in a 3D environment.
|
data/bin/clients/simple/main.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# A simple motel client executable
|
3
|
-
# Executable to use the motel library to perform operations on
|
4
|
-
# a remote location server, simply printing out results
|
5
|
-
#
|
6
|
-
# Flags: (see below)
|
7
|
-
#
|
8
|
-
# Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
|
9
|
-
# Licensed under the AGPLv3+ http://www.gnu.org/licenses/agpl.txt
|
10
|
-
|
11
|
-
CURRENT_DIR=File.dirname(__FILE__)
|
12
|
-
$: << File.expand_path(CURRENT_DIR + "/../../../lib")
|
13
|
-
|
14
|
-
require 'rubygems'
|
15
|
-
require 'optparse'
|
16
|
-
require 'motel'
|
17
|
-
|
18
|
-
include Motel
|
19
|
-
include Motel::MovementStrategies
|
20
|
-
|
21
|
-
######################
|
22
|
-
|
23
|
-
# TODO movement strategy support
|
24
|
-
|
25
|
-
def main()
|
26
|
-
# command line parameters
|
27
|
-
schema_file = nil
|
28
|
-
location = {:parent_id => nil,
|
29
|
-
:x => nil,
|
30
|
-
:y => nil,
|
31
|
-
:z => nil}
|
32
|
-
request_target = nil
|
33
|
-
|
34
|
-
# setup cmd line options
|
35
|
-
opts = OptionParser.new do |opts|
|
36
|
-
opts.banner = "Usage: main.rb [command] [options]"
|
37
|
-
|
38
|
-
opts.on("-h", "--help", "Print this help message") do
|
39
|
-
puts opts
|
40
|
-
exit
|
41
|
-
end
|
42
|
-
|
43
|
-
opts.on("-s", "--schema [path]", "Motel Schema File") do |path|
|
44
|
-
schema_file = path
|
45
|
-
end
|
46
|
-
|
47
|
-
opts.separator ""
|
48
|
-
opts.separator "Commands:"
|
49
|
-
opts.on("-g", "--get", "get location specified by id")do
|
50
|
-
request_target = :get_location
|
51
|
-
end
|
52
|
-
opts.on("-c", "--create", "create location w/ id")do
|
53
|
-
request_target = :create_location
|
54
|
-
end
|
55
|
-
opts.on("-u", "--update", "update location specified by id w/ specified options")do
|
56
|
-
request_target = :update_location
|
57
|
-
end
|
58
|
-
opts.on("-b", "--subscribe", "subscribe to updates to location specified by id")do
|
59
|
-
request_target = :subscribe_to_location
|
60
|
-
end
|
61
|
-
|
62
|
-
opts.separator ""
|
63
|
-
opts.separator "Options:"
|
64
|
-
opts.on("-i", "--id [location_id]", "Target location id") do |id|
|
65
|
-
location[:id] = id
|
66
|
-
end
|
67
|
-
opts.on("-p", "--parent-id [location_id]", "Target parent location id") do |id|
|
68
|
-
location[:parent_id] = id
|
69
|
-
end
|
70
|
-
opts.on("-x", "--xcoordinate [coordinate]", "Target location x coordinate") do |x|
|
71
|
-
location[:x] = x
|
72
|
-
end
|
73
|
-
opts.on("-y", "--ycoordinate [coordinate]", "Target location y coordinate") do |y|
|
74
|
-
location[:y] = y
|
75
|
-
end
|
76
|
-
opts.on("-z", "--zcoordinate [coordinate]", "Target location z coordinate") do |z|
|
77
|
-
location[:z] = z
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
# parse cmd line
|
83
|
-
begin
|
84
|
-
opts.parse!(ARGV)
|
85
|
-
rescue OptionParser::InvalidOption => e
|
86
|
-
puts opts
|
87
|
-
puts e.to_s
|
88
|
-
exit
|
89
|
-
end
|
90
|
-
|
91
|
-
if request_target.nil? || location[:id].nil? || schema_file.nil? ||
|
92
|
-
request_target == :update && location[:x].nil? && location[:y].nil? && location[:z].nil? && location[:parent_id].nil?
|
93
|
-
puts opts
|
94
|
-
puts "must specify schema, a command to perform, a location id, and other required options"
|
95
|
-
exit
|
96
|
-
end
|
97
|
-
|
98
|
-
lid = location[:id]
|
99
|
-
location = Motel::Location.new :id => location[:id],
|
100
|
-
:parent_id => location[:parent_id],
|
101
|
-
:x => location[:x],
|
102
|
-
:y => location[:y],
|
103
|
-
:z => location[:z]
|
104
|
-
args = []
|
105
|
-
case(request_target)
|
106
|
-
when :get_location
|
107
|
-
args.push location.id
|
108
|
-
when :create_location
|
109
|
-
args.push location.id
|
110
|
-
when :update_location
|
111
|
-
args.push location
|
112
|
-
when :subscribe_to_location
|
113
|
-
args.push location.id
|
114
|
-
end
|
115
|
-
|
116
|
-
# FIXME need configurable amqp broker ip/port
|
117
|
-
client = Motel::Client.new :schema_file => schema_file
|
118
|
-
result = client.request request_target, *args
|
119
|
-
|
120
|
-
if request_target == :subscribe_to_location
|
121
|
-
client.on_location_received = lambda { |loc|
|
122
|
-
puts "location received:"
|
123
|
-
puts "#{loc}"
|
124
|
-
}
|
125
|
-
client.join
|
126
|
-
end
|
127
|
-
|
128
|
-
puts "server returned #{result}"
|
129
|
-
end
|
130
|
-
|
131
|
-
main()
|
data/lib/motel/simrpc.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
# Motel simrpc adapter
|
2
|
-
#
|
3
|
-
# Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
|
4
|
-
# Licensed under the AGPLv3+ http://www.gnu.org/licenses/agpl.txt
|
5
|
-
|
6
|
-
require 'simrpc'
|
7
|
-
|
8
|
-
module Motel
|
9
|
-
|
10
|
-
# Motel::Server defines a server endpoint which manages locations
|
11
|
-
# and responds to simrpc requests
|
12
|
-
class Server
|
13
|
-
def initialize(args = {})
|
14
|
-
simrpc_args = args
|
15
|
-
simrpc_args[:id] = "location-server"
|
16
|
-
|
17
|
-
# create a simprc node
|
18
|
-
@simrpc_node = Simrpc::Node.new(simrpc_args)
|
19
|
-
|
20
|
-
# register handlers for the various motel simrpc methods
|
21
|
-
@simrpc_node.handle_method("get_location") { |location_id|
|
22
|
-
Logger.info "received get location #{location_id} request"
|
23
|
-
loc = nil
|
24
|
-
begin
|
25
|
-
loc = Runner.instance.locations.find { |loc| loc.id == location_id }
|
26
|
-
# FIXME traverse all of loc's descendants, and if remote location
|
27
|
-
# server is specified, send request to get child location, swapping
|
28
|
-
# it in for the one thats there
|
29
|
-
rescue Exception => e
|
30
|
-
Logger.warn "get location #{location_id} failed w/ exception #{e}"
|
31
|
-
end
|
32
|
-
Logger.info "get location #{location_id} request returning #{loc}"
|
33
|
-
loc
|
34
|
-
}
|
35
|
-
|
36
|
-
@simrpc_node.handle_method("create_location") { |location_id|
|
37
|
-
Logger.info "received create location #{location_id} request"
|
38
|
-
success = true
|
39
|
-
begin
|
40
|
-
Runner.instance.run Location.new(:id => location_id)
|
41
|
-
# TODO decendants support w/ remote option (create additional locations on other servers)
|
42
|
-
rescue Exception => e
|
43
|
-
Logger.warn "create location #{location_id} failed w/ exception #{e}"
|
44
|
-
success = false
|
45
|
-
end
|
46
|
-
Logger.info "create location #{location_id} request returning #{success}"
|
47
|
-
success
|
48
|
-
}
|
49
|
-
|
50
|
-
@simrpc_node.handle_method("update_location") { |location|
|
51
|
-
Logger.info "received update location #{location.id} request"
|
52
|
-
success = true
|
53
|
-
if location.nil?
|
54
|
-
success = false
|
55
|
-
else
|
56
|
-
rloc = Runner.instance.locations.find { |loc| loc.id == location.id }
|
57
|
-
begin
|
58
|
-
Logger.info "updating location #{location.id} with #{location}/#{location.movement_strategy}"
|
59
|
-
rloc.update(location)
|
60
|
-
rescue Exception => e
|
61
|
-
Logger.warn "update location #{location.id} failed w/ exception #{e}"
|
62
|
-
success = false
|
63
|
-
end
|
64
|
-
end
|
65
|
-
Logger.info "update location #{location.id} returning #{success}"
|
66
|
-
success
|
67
|
-
}
|
68
|
-
|
69
|
-
@simrpc_node.handle_method("subscribe_to_location") { |location_id, client_id|
|
70
|
-
Logger.info "subscribe client #{client_id} to location #{location_id} request received"
|
71
|
-
loc = Runner.instance.locations.find { |loc| loc.id == location_id }
|
72
|
-
success = true
|
73
|
-
if loc.nil?
|
74
|
-
success = false
|
75
|
-
else
|
76
|
-
loc.movement_callbacks.push lambda { |location|
|
77
|
-
# send location to client
|
78
|
-
@simrpc_node.send_method("location_moved", client_id, location)
|
79
|
-
}
|
80
|
-
end
|
81
|
-
Logger.info "subscribe client #{client_id} to location #{location_id} returning #{success}"
|
82
|
-
success
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
|
-
def join
|
87
|
-
@simrpc_node.join
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Client defines a client endpoint that performs
|
92
|
-
# a request against a Motel Server
|
93
|
-
class Client
|
94
|
-
# should be a callable object that takes a location to be
|
95
|
-
# invoked when the server sends a location to the client
|
96
|
-
attr_writer :on_location_received
|
97
|
-
|
98
|
-
# Initialize the client with various args, all of which are passed onto Simrpc::Node constructor
|
99
|
-
def initialize(args = {})
|
100
|
-
simrpc_args = args
|
101
|
-
simrpc_args[:destination] = "location-server"
|
102
|
-
|
103
|
-
@simrpc_node = Simrpc::Node.new(simrpc_args)
|
104
|
-
end
|
105
|
-
|
106
|
-
def join
|
107
|
-
@simrpc_node.join
|
108
|
-
end
|
109
|
-
|
110
|
-
def request(target, *args)
|
111
|
-
method_missing(target, *args)
|
112
|
-
end
|
113
|
-
|
114
|
-
# pass simrpc method requests right onto the simrpc node
|
115
|
-
def method_missing(method_id, *args)
|
116
|
-
# special case for subsscribe_to_location,
|
117
|
-
if method_id == :subscribe_to_location
|
118
|
-
# add simrpc node id onto args list
|
119
|
-
args.push @simrpc_node.id
|
120
|
-
|
121
|
-
# handle location updates from the server, & issue subscribe request
|
122
|
-
@simrpc_node.handle_method("location_moved") { |location|
|
123
|
-
Logger.info "location #{location.id} moved"
|
124
|
-
@on_location_received.call(location) unless @on_location_received.nil?
|
125
|
-
}
|
126
|
-
end
|
127
|
-
@simrpc_node.method_missing(method_id, *args)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
data/lib/motel/thread_pool.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# copied unmodified from the ruby cookbook
|
2
|
-
# http://codeidol.com/other/rubyckbk/Multitasking-and-Multithreading/Limiting-Multithreading-with-a-Thread-Pool/
|
3
|
-
|
4
|
-
require 'thread'
|
5
|
-
|
6
|
-
class ThreadPool
|
7
|
-
attr_reader :max_size
|
8
|
-
|
9
|
-
def initialize(max_size)
|
10
|
-
@pool = []
|
11
|
-
@max_size = max_size
|
12
|
-
@pool_mutex = Mutex.new
|
13
|
-
@pool_cv = ConditionVariable.new
|
14
|
-
end
|
15
|
-
|
16
|
-
def dispatch(*args)
|
17
|
-
Thread.new do
|
18
|
-
# Wait for space in the pool.
|
19
|
-
@pool_mutex.synchronize do
|
20
|
-
while @pool.size >= @max_size
|
21
|
-
print "Pool is full; waiting to run #{args.join(',')}…\n" if $DEBUG
|
22
|
-
# Sleep until some other thread calls @pool_cv.signal.
|
23
|
-
@pool_cv.wait(@pool_mutex)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
@pool << Thread.current
|
27
|
-
begin
|
28
|
-
yield(*args)
|
29
|
-
rescue => e
|
30
|
-
exception(self, e, *args)
|
31
|
-
ensure
|
32
|
-
@pool_mutex.synchronize do
|
33
|
-
# Remove the thread from the pool.
|
34
|
-
@pool.delete(Thread.current)
|
35
|
-
# Signal the next waiting thread that there's a space in the pool.
|
36
|
-
@pool_cv.signal
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def shutdown
|
43
|
-
@pool_mutex.synchronize { @pool_cv.wait(@pool_mutex) until @pool.empty? }
|
44
|
-
end
|
45
|
-
|
46
|
-
def exception(thread, exception, *original_args)
|
47
|
-
# Subclass this method to handle an exception within a thread.
|
48
|
-
puts "Exception in thread #{thread}: #{exception}"
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|