starling 0.9.8 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/README.rdoc +9 -7
- data/Rakefile +42 -13
- data/etc/starling.redhat +50 -47
- data/etc/starling.ubuntu +1 -1
- data/lib/starling.rb +46 -10
- data/lib/starling/handler.rb +38 -23
- data/lib/starling/persistent_queue.rb +5 -0
- data/lib/starling/queue_collection.rb +6 -0
- data/lib/starling/server.rb +15 -8
- data/lib/starling/server_runner.rb +30 -5
- data/spec/starling_server_spec.rb +17 -4
- metadata +25 -24
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
== 0.10.1 (future)
|
2
|
+
* Fixed a potential privilege escalation issue <jdamato@alumni.cmu.edu>
|
3
|
+
|
4
|
+
== 0.10.0
|
5
|
+
* Solved compatibility issues with the new (and awesome, thanks mperham) Memcache client
|
6
|
+
* Fixed the old rspec tests.
|
7
|
+
|
8
|
+
== 0.9.9
|
9
|
+
* remove dependency on SyslogLogger so that starling works on windows.
|
10
|
+
* fix config file loading so relative paths are expanded properly <jacob@jacobatzen.dk>
|
11
|
+
* clean up redhat init.d script <gaffneyc@gmail.com>
|
12
|
+
* add a 'fetch' command that is non-blocking equivalent to 'get' <aaron.hawkins@shawkvalue.com>
|
13
|
+
* implement the 'delete' method to allow queues to be deleted <timshadel@gmail.com>
|
14
|
+
|
1
15
|
== 0.9.8
|
2
16
|
* add fix to enable relative paths <david@motorator.com>
|
3
17
|
* fix tests so they don't run 10 times due to a stupid bug with how the server is forked <seth@mojodna.net>
|
data/README.rdoc
CHANGED
@@ -11,7 +11,7 @@ that speaks MemCache can take advantage of Starling's queue facilities.
|
|
11
11
|
|
12
12
|
= Installation
|
13
13
|
|
14
|
-
|
14
|
+
The Starling source is hosted at GitHub and can be found at:
|
15
15
|
|
16
16
|
http://github.com/starling/starling/tree/master
|
17
17
|
|
@@ -44,7 +44,7 @@ that speaks MemCache can take advantage of Starling's queue facilities.
|
|
44
44
|
>> require 'starling'
|
45
45
|
=> true
|
46
46
|
>> starling = Starling.new('127.0.0.1:22122')
|
47
|
-
=> MemCache: 1 servers,
|
47
|
+
=> MemCache: 1 servers, ns: nil, ro: false
|
48
48
|
>> starling.set('my_queue', 12345)
|
49
49
|
=> nil
|
50
50
|
>> starling.get('my_queue')
|
@@ -67,13 +67,13 @@ that speaks MemCache can take advantage of Starling's queue facilities.
|
|
67
67
|
|
68
68
|
'rdoc'
|
69
69
|
|
70
|
-
= Using
|
70
|
+
= Using memcache-client
|
71
71
|
|
72
|
-
memcache-client
|
72
|
+
memcache-client is now maintained by Mike Perham (http://www.mikeperham.com/)
|
73
73
|
|
74
|
-
|
74
|
+
He is the current maintainer of the gem which is hosted at GitHub and can be found at:
|
75
75
|
|
76
|
-
|
76
|
+
http://github.com/mperham/memcache-client/tree/master
|
77
77
|
|
78
78
|
It can be installed using:
|
79
79
|
|
@@ -81,10 +81,11 @@ that speaks MemCache can take advantage of Starling's queue facilities.
|
|
81
81
|
gem sources -a http://gems.github.com/
|
82
82
|
|
83
83
|
# As often as you like
|
84
|
-
sudo gem install
|
84
|
+
sudo gem install memcache-client
|
85
85
|
|
86
86
|
= Known Issues
|
87
87
|
|
88
|
+
* Only tested with Memcache client 1.7.x and with SystemTimer (http://systemtimer.rubyforge.org/)
|
88
89
|
* Starling is "slow" as far as messaging systems are concerned. In practice,
|
89
90
|
it's fast enough.
|
90
91
|
|
@@ -99,6 +100,7 @@ that speaks MemCache can take advantage of Starling's queue facilities.
|
|
99
100
|
* AnotherBritt <?>
|
100
101
|
* Glenn Rempe <?>
|
101
102
|
* Abdul-Rahman Advany <abdulrahman@advany.com>
|
103
|
+
* Harm Aarts <harmaarts@gmail.com>
|
102
104
|
|
103
105
|
= Copyright
|
104
106
|
|
data/Rakefile
CHANGED
@@ -1,22 +1,51 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'rake
|
3
|
-
require 'spec/rake/spectask'
|
4
|
-
|
5
|
-
task :default => :spec
|
2
|
+
require 'rake'
|
6
3
|
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "starling"
|
9
|
+
s.version = "0.10.0"
|
10
|
+
s.authors = ["Blaine Cook", "Chris Wanstrath", "Britt Selvitelle", "Glenn Rempe", "Abdul-Rahman Advany", "Seth Fitzsimmons", "Harm Aarts", "Chris Gaffney"]
|
11
|
+
s.email = ["blaine@twitter.com", "chris@ozmm.org", "abdulrahman@advany.com", "starlingmq@groups.google.com", "harmaarts@gmail.com", "gaffneyc@gmail.com"]
|
12
|
+
s.homepage = "http://github.com/starling/starling/"
|
13
|
+
s.summary = "Starling is a lightweight, transactional, distributed queue server"
|
14
|
+
s.description = s.summary
|
15
|
+
|
16
|
+
s.executables = ["starling", "starling_top"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.rdoc_options = ["--quiet", "--title", "starling documentation", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
|
21
|
+
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "LICENSE"]
|
22
|
+
|
23
|
+
s.add_dependency 'memcache-client', [">= 1.7.0"]
|
24
|
+
s.add_dependency 'eventmachine', [">= 0.12.0"]
|
25
|
+
end
|
26
|
+
|
27
|
+
Jeweler::GemcutterTasks.new
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
10
30
|
end
|
11
31
|
|
12
|
-
|
13
|
-
t.ruby_opts = ['-rtest/unit']
|
14
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
15
|
-
t.fail_on_error = true
|
16
|
-
end
|
17
|
-
|
32
|
+
require 'rake/rdoctask'
|
18
33
|
Rake::RDocTask.new do |rd|
|
19
34
|
rd.main = "README.rdoc"
|
20
35
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
21
36
|
rd.rdoc_dir = 'doc'
|
22
37
|
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'spec/rake/spectask'
|
43
|
+
|
44
|
+
Spec::Rake::SpecTask.new do |t|
|
45
|
+
t.ruby_opts = ['-rtest/unit']
|
46
|
+
t.spec_files = FileList['spec/*_spec.rb']
|
47
|
+
t.fail_on_error = true
|
48
|
+
end
|
49
|
+
rescue LoadError
|
50
|
+
puts "RSpec (or a dependency) not available. Install it with: sudo gem install rspec"
|
51
|
+
end
|
data/etc/starling.redhat
CHANGED
@@ -1,63 +1,66 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
#
|
3
|
+
# Make sure the /var/run/starling, /var/log/starling and /var/spool/starling
|
4
|
+
# all exist and are owned by starling:starling
|
5
|
+
#
|
3
6
|
# starling This shell script takes care of starting and stopping
|
4
7
|
# the starling server
|
5
8
|
# chkconfig: 345 98 98
|
6
9
|
# description: The starling queue server
|
10
|
+
# processname: starling
|
11
|
+
# pidfile: /var/run/starling/starling.pid
|
12
|
+
# logfile: /var/log/starling/starling.log
|
13
|
+
|
14
|
+
# Source function library.
|
15
|
+
. /etc/rc.d/init.d/functions
|
16
|
+
|
17
|
+
# Source networking configuration.
|
18
|
+
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
|
19
|
+
|
20
|
+
DUSER=starling
|
21
|
+
DGROUP=starling
|
22
|
+
LOGFILE=/var/log/starling/starling.log
|
23
|
+
SPOOLDIR=/var/spool/starling
|
24
|
+
PORT=22122
|
25
|
+
LISTEN=0.0.0.0
|
26
|
+
PIDFILE=/var/run/starling/starling.pid
|
7
27
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
elif [ -e /usr/local/bin/pidof ]; then
|
14
|
-
PIDOF="/usr/local/bin/pidof"
|
15
|
-
elif [ -e /bin/pgrep ]; then
|
16
|
-
PIDOF="/bin/pgrep"
|
17
|
-
elif [ -e /usr/bin/pgrep ]; then
|
18
|
-
PIDOF="/usr/bin/pgrep"
|
19
|
-
elif [ -e /usr/local/bin/pgrep ]; then
|
20
|
-
PIDOF="/usr/local/bin/pgrep"
|
21
|
-
else
|
22
|
-
echo "Could not find pidof or pgrep"
|
23
|
-
fi
|
24
|
-
|
25
|
-
PROGDIR="/usr/bin"
|
26
|
-
PROGNAME="starling"
|
27
|
-
OPTIONS="-u nobody -g nobody -L /var/log/starling.log -q /var/spool/starling"
|
28
|
+
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
29
|
+
NAME=starling
|
30
|
+
INSTALL_DIR=/usr/local/bin
|
31
|
+
DAEMON=$INSTALL_DIR/$NAME
|
32
|
+
OPTS="-h $LISTEN -p $PORT -d -q $SPOOLDIR -P $PIDFILE -L $LOGFILE -u $DUSER -g $DGROUP"
|
28
33
|
|
29
34
|
start() {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
echo "Starting $PROGDIR$PROGNAME"
|
35
|
-
cd $PROGDIR
|
36
|
-
nohup $PROGDIR$PROGNAME $OPTIONS &
|
37
|
-
fi
|
35
|
+
echo -n $"Starting starling: "
|
36
|
+
|
37
|
+
daemon --pidfile=$PIDFILE $DAEMON $OPTS
|
38
|
+
echo
|
38
39
|
}
|
39
40
|
|
40
41
|
stop() {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
else
|
46
|
-
echo "$PROGDIR$PROGNAME not running"
|
47
|
-
fi
|
42
|
+
echo -n $"Stopping starling: "
|
43
|
+
|
44
|
+
killproc -p $PIDFILE starling
|
45
|
+
echo
|
48
46
|
}
|
49
47
|
|
50
48
|
case "$1" in
|
51
|
-
start)
|
52
|
-
|
53
|
-
;;
|
54
|
-
stop)
|
55
|
-
|
56
|
-
;;
|
57
|
-
restart)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
;;
|
62
|
-
|
49
|
+
start)
|
50
|
+
start
|
51
|
+
;;
|
52
|
+
stop)
|
53
|
+
stop
|
54
|
+
;;
|
55
|
+
restart)
|
56
|
+
stop
|
57
|
+
sleep 3
|
58
|
+
start
|
59
|
+
;;
|
60
|
+
status)
|
61
|
+
status -p $PIDFILE starling
|
62
|
+
;;
|
63
|
+
*)
|
64
|
+
echo $"Usage: $0 {start|stop|restart|status}"
|
65
|
+
exit 1
|
63
66
|
esac
|
data/etc/starling.ubuntu
CHANGED
data/lib/starling.rb
CHANGED
@@ -3,18 +3,53 @@ require 'memcache'
|
|
3
3
|
class Starling < MemCache
|
4
4
|
|
5
5
|
WAIT_TIME = 0.25
|
6
|
+
alias_method :_original_get, :get
|
7
|
+
alias_method :_original_delete, :delete
|
6
8
|
|
7
9
|
##
|
8
10
|
# fetch an item from a queue.
|
9
11
|
|
10
12
|
def get(*args)
|
11
13
|
loop do
|
12
|
-
response =
|
14
|
+
response = _original_get(*args)
|
13
15
|
return response unless response.nil?
|
14
16
|
sleep WAIT_TIME
|
15
17
|
end
|
16
18
|
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# will return the next item or nil
|
22
|
+
|
23
|
+
def fetch(*args)
|
24
|
+
_original_get(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Delete the key (queue) from all Starling servers. This is necessary
|
29
|
+
# because the random way a server is chosen in #get_server_for_key
|
30
|
+
# implies that the queue could easily be spread across the entire
|
31
|
+
# Starling cluster.
|
32
|
+
|
33
|
+
def delete(key, expiry = 0)
|
34
|
+
with_servers do
|
35
|
+
_original_delete(key, expiry)
|
36
|
+
end
|
37
|
+
end
|
17
38
|
|
39
|
+
##
|
40
|
+
# Provides a way to work with a specific list of servers by
|
41
|
+
# forcing all calls to #get_server_for_key to use a specific
|
42
|
+
# server, and changing that server each time that the call
|
43
|
+
# yields to the block provided. This helps work around the
|
44
|
+
# normally random nature of the #get_server_for_key method.
|
45
|
+
#
|
46
|
+
def with_servers(my_servers = self.servers.dup)
|
47
|
+
return unless block_given?
|
48
|
+
my_servers.each do |server|
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
18
53
|
##
|
19
54
|
# insert +value+ into +queue+.
|
20
55
|
#
|
@@ -89,16 +124,17 @@ class Starling < MemCache
|
|
89
124
|
def get_server_for_key(key)
|
90
125
|
raise ArgumentError, "illegal character in key #{key.inspect}" if key =~ /\s/
|
91
126
|
raise ArgumentError, "key too long #{key.inspect}" if key.length > 250
|
92
|
-
raise MemCacheError, "No servers available" if
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
127
|
+
raise MemCacheError, "No servers available" if servers.empty?
|
128
|
+
|
129
|
+
# Ignores server weights, oh well
|
130
|
+
srvs = servers.dup
|
131
|
+
srvs.size.times do |try|
|
132
|
+
n = rand(srvs.size)
|
133
|
+
server = srvs[n]
|
98
134
|
return server if server.alive?
|
99
|
-
|
135
|
+
srvs.delete_at(n)
|
100
136
|
end
|
101
|
-
|
137
|
+
|
102
138
|
raise MemCacheError, "No servers available (all dead)"
|
103
139
|
end
|
104
|
-
end
|
140
|
+
end
|
data/lib/starling/handler.rb
CHANGED
@@ -22,36 +22,41 @@ module StarlingServer
|
|
22
22
|
SET_RESPONSE_SUCCESS = "STORED\r\n".freeze
|
23
23
|
SET_RESPONSE_FAILURE = "NOT STORED\r\n".freeze
|
24
24
|
SET_CLIENT_DATA_ERROR = "CLIENT_ERROR bad data chunk\r\nERROR\r\n".freeze
|
25
|
+
|
26
|
+
# DELETE Responses
|
27
|
+
DELETE_COMMAND = /\Adelete (.{1,250}) ([0-9]+)\r\n/m
|
28
|
+
DELETE_RESPONSE = "END\r\n".freeze
|
25
29
|
|
26
30
|
# STAT Response
|
27
31
|
STATS_COMMAND = /\Astats\r\n/m
|
28
|
-
STATS_RESPONSE = "STAT pid %d
|
29
|
-
STAT uptime %d
|
30
|
-
STAT time %d
|
31
|
-
STAT version %s
|
32
|
-
STAT rusage_user %0.6f
|
33
|
-
STAT rusage_system %0.6f
|
34
|
-
STAT curr_items %d
|
35
|
-
STAT total_items %d
|
36
|
-
STAT bytes %d
|
37
|
-
STAT curr_connections %d
|
38
|
-
STAT total_connections %d
|
39
|
-
STAT cmd_get %d
|
40
|
-
STAT cmd_set %d
|
41
|
-
STAT get_hits %d
|
42
|
-
STAT get_misses %d
|
43
|
-
STAT bytes_read %d
|
44
|
-
STAT bytes_written %d
|
45
|
-
STAT limit_maxbytes %d
|
32
|
+
STATS_RESPONSE = "STAT pid %d\r
|
33
|
+
STAT uptime %d\r
|
34
|
+
STAT time %d\r
|
35
|
+
STAT version %s\r
|
36
|
+
STAT rusage_user %0.6f\r
|
37
|
+
STAT rusage_system %0.6f\r
|
38
|
+
STAT curr_items %d\r
|
39
|
+
STAT total_items %d\r
|
40
|
+
STAT bytes %d\r
|
41
|
+
STAT curr_connections %d\r
|
42
|
+
STAT total_connections %d\r
|
43
|
+
STAT cmd_get %d\r
|
44
|
+
STAT cmd_set %d\r
|
45
|
+
STAT get_hits %d\r
|
46
|
+
STAT get_misses %d\r
|
47
|
+
STAT bytes_read %d\r
|
48
|
+
STAT bytes_written %d\r
|
49
|
+
STAT limit_maxbytes %d\r
|
46
50
|
%sEND\r\n".freeze
|
47
|
-
QUEUE_STATS_RESPONSE = "STAT queue_%s_items %d
|
48
|
-
STAT queue_%s_total_items %d
|
49
|
-
STAT queue_%s_logsize %d
|
50
|
-
STAT queue_%s_expired_items %d
|
51
|
+
QUEUE_STATS_RESPONSE = "STAT queue_%s_items %d\r
|
52
|
+
STAT queue_%s_total_items %d\r
|
53
|
+
STAT queue_%s_logsize %d\r
|
54
|
+
STAT queue_%s_expired_items %d\r
|
51
55
|
STAT queue_%s_age %d\r\n".freeze
|
52
56
|
|
53
57
|
SHUTDOWN_COMMAND = /\Ashutdown\r\n/m
|
54
58
|
|
59
|
+
QUIT_COMMAND = /\Aquit\r\n/m
|
55
60
|
|
56
61
|
@@next_session_id = 1
|
57
62
|
|
@@ -108,7 +113,6 @@ STAT queue_%s_age %d\r\n".freeze
|
|
108
113
|
@data_buf = data
|
109
114
|
return
|
110
115
|
end
|
111
|
-
|
112
116
|
case data
|
113
117
|
when SET_COMMAND
|
114
118
|
@server.stats[:set_requests] += 1
|
@@ -121,6 +125,11 @@ STAT queue_%s_age %d\r\n".freeze
|
|
121
125
|
when SHUTDOWN_COMMAND
|
122
126
|
# no point in responding, they'll never get it.
|
123
127
|
Runner::shutdown
|
128
|
+
when DELETE_COMMAND
|
129
|
+
delete $1
|
130
|
+
when QUIT_COMMAND
|
131
|
+
# ignore the command, client is closing connection.
|
132
|
+
return nil
|
124
133
|
else
|
125
134
|
logger.warn "Unknown command: #{data}."
|
126
135
|
respond ERR_UNKNOWN_COMMAND
|
@@ -136,6 +145,12 @@ STAT queue_%s_age %d\r\n".freeze
|
|
136
145
|
end
|
137
146
|
|
138
147
|
private
|
148
|
+
|
149
|
+
def delete(queue)
|
150
|
+
@queue_collection.delete(queue)
|
151
|
+
respond DELETE_RESPONSE
|
152
|
+
end
|
153
|
+
|
139
154
|
def respond(str, *args)
|
140
155
|
response = sprintf(str, *args)
|
141
156
|
@server.stats[:bytes_written] += response.length
|
data/lib/starling/server.rb
CHANGED
@@ -2,7 +2,6 @@ require 'socket'
|
|
2
2
|
require 'logger'
|
3
3
|
require 'rubygems'
|
4
4
|
require 'eventmachine'
|
5
|
-
require 'analyzer_tools/syslog_logger'
|
6
5
|
|
7
6
|
here = File.dirname(__FILE__)
|
8
7
|
|
@@ -11,7 +10,7 @@ require File.join(here, 'handler')
|
|
11
10
|
|
12
11
|
module StarlingServer
|
13
12
|
|
14
|
-
VERSION = "0.
|
13
|
+
VERSION = "0.10.0"
|
15
14
|
|
16
15
|
class Base
|
17
16
|
attr_reader :logger
|
@@ -68,12 +67,20 @@ module StarlingServer
|
|
68
67
|
def run
|
69
68
|
@stats[:start_time] = Time.now
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
if @opts[:syslog_channel]
|
71
|
+
begin
|
72
|
+
require 'syslog_logger'
|
73
|
+
@@logger = SyslogLogger.new(@opts[:syslog_channel])
|
74
|
+
rescue LoadError
|
75
|
+
# SyslogLogger isn't available, so we're just going to use Logger
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
@@logger ||= case @opts[:logger]
|
80
|
+
when IO, String; Logger.new(@opts[:logger])
|
81
|
+
when Logger; @opts[:logger]
|
82
|
+
else; Logger.new(STDERR)
|
83
|
+
end
|
77
84
|
|
78
85
|
begin
|
79
86
|
@opts[:queue] = QueueCollection.new(@opts[:path])
|
@@ -1,6 +1,9 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'server')
|
2
|
+
require 'erb'
|
3
|
+
require 'fileutils'
|
2
4
|
require 'optparse'
|
3
5
|
require 'yaml'
|
6
|
+
require 'fileutils'
|
4
7
|
|
5
8
|
module StarlingServer
|
6
9
|
class Runner
|
@@ -34,12 +37,29 @@ module StarlingServer
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def load_config_file(filename)
|
37
|
-
YAML.load(File.
|
40
|
+
config = YAML.load(ERB.new(File.read(filename)).result)
|
41
|
+
|
42
|
+
unless config.is_a?(Hash)
|
43
|
+
STDERR.puts "Config file does not contain a hash: #{filename}, exiting."
|
44
|
+
exit(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
if config['starling'].nil?
|
48
|
+
STDERR.puts "Missing starling section in config file: #{filename}, exiting."
|
49
|
+
exit(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
config['starling'].each do |key, value|
|
38
53
|
# alias some keys
|
39
54
|
case key
|
40
55
|
when "queue_path" then key = "path"
|
41
56
|
when "log_file" then key = "logger"
|
42
57
|
end
|
58
|
+
|
59
|
+
if %w(logger path pid_file).include?(key)
|
60
|
+
value = File.expand_path(value)
|
61
|
+
end
|
62
|
+
|
43
63
|
options[key.to_sym] = value
|
44
64
|
|
45
65
|
if options[:log_level].instance_of?(String)
|
@@ -113,8 +133,13 @@ module StarlingServer
|
|
113
133
|
options[:logger] = File.expand_path(log_path)
|
114
134
|
end
|
115
135
|
|
116
|
-
|
117
|
-
|
136
|
+
begin
|
137
|
+
require 'syslog_logger'
|
138
|
+
|
139
|
+
opts.on("-l", "--syslog CHANNEL", "Write logs to the syslog instead of a log file.") do |channel|
|
140
|
+
options[:syslog_channel] = channel
|
141
|
+
end
|
142
|
+
rescue LoadError
|
118
143
|
end
|
119
144
|
|
120
145
|
opts.on("-v", "Increase logging verbosity (may be used multiple times).") do
|
@@ -157,8 +182,8 @@ module StarlingServer
|
|
157
182
|
end
|
158
183
|
|
159
184
|
def drop_privileges
|
160
|
-
Process.
|
161
|
-
Process.
|
185
|
+
Process::Sys.setgid(options[:group]) if options[:group]
|
186
|
+
Process::Sys.setuid(options[:user]) if options[:user]
|
162
187
|
end
|
163
188
|
|
164
189
|
def shutdown
|
@@ -4,6 +4,7 @@ require 'rubygems'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'memcache'
|
6
6
|
require 'digest/md5'
|
7
|
+
require 'starling'
|
7
8
|
|
8
9
|
require 'starling/server'
|
9
10
|
|
@@ -51,6 +52,7 @@ describe "StarlingServer" do
|
|
51
52
|
end
|
52
53
|
|
53
54
|
@client = MemCache.new('127.0.0.1:22133')
|
55
|
+
|
54
56
|
end
|
55
57
|
|
56
58
|
it "should test if temp_path exists and is writeable" do
|
@@ -66,6 +68,15 @@ describe "StarlingServer" do
|
|
66
68
|
@client.get('test_set_and_get_one_entry').should eql(v)
|
67
69
|
end
|
68
70
|
|
71
|
+
it "should respond to delete" do
|
72
|
+
@client.delete("my_queue").should eql("END\r\n")
|
73
|
+
starling_client = Starling.new('127.0.0.1:22133')
|
74
|
+
starling_client.set('my_queue', 50)
|
75
|
+
starling_client.available_queues.size.should eql(1)
|
76
|
+
starling_client.delete("my_queue")
|
77
|
+
starling_client.available_queues.size.should eql(0)
|
78
|
+
end
|
79
|
+
|
69
80
|
it "should expire entries" do
|
70
81
|
v = rand((2**32)-1)
|
71
82
|
@client.get('test_set_with_expiry').should be_nil
|
@@ -113,8 +124,8 @@ describe "StarlingServer" do
|
|
113
124
|
|
114
125
|
it "should output statistics per server" do
|
115
126
|
stats = @client.stats
|
116
|
-
|
117
|
-
|
127
|
+
stats.kind_of? Hash
|
128
|
+
stats.has_key?('127.0.0.1:22133').should be_true
|
118
129
|
|
119
130
|
server_stats = stats['127.0.0.1:22133']
|
120
131
|
|
@@ -129,8 +140,10 @@ describe "StarlingServer" do
|
|
129
140
|
end
|
130
141
|
|
131
142
|
it "should return valid response with unkown command" do
|
132
|
-
|
133
|
-
|
143
|
+
#why is this an unknown command?
|
144
|
+
lambda {
|
145
|
+
response = @client.add('blah', 1)
|
146
|
+
}.should raise_error(MemCache::MemCacheError)
|
134
147
|
end
|
135
148
|
|
136
149
|
it "should disconnect and reconnect again" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: starling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blaine Cook
|
@@ -9,11 +9,14 @@ authors:
|
|
9
9
|
- Britt Selvitelle
|
10
10
|
- Glenn Rempe
|
11
11
|
- Abdul-Rahman Advany
|
12
|
+
- Seth Fitzsimmons
|
13
|
+
- Harm Aarts
|
14
|
+
- Chris Gaffney
|
12
15
|
autorequire:
|
13
16
|
bindir: bin
|
14
17
|
cert_chain: []
|
15
18
|
|
16
|
-
date:
|
19
|
+
date: 2010-01-20 00:00:00 +02:00
|
17
20
|
default_executable:
|
18
21
|
dependencies:
|
19
22
|
- !ruby/object:Gem::Dependency
|
@@ -24,17 +27,7 @@ dependencies:
|
|
24
27
|
requirements:
|
25
28
|
- - ">="
|
26
29
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
28
|
-
version:
|
29
|
-
- !ruby/object:Gem::Dependency
|
30
|
-
name: SyslogLogger
|
31
|
-
type: :runtime
|
32
|
-
version_requirement:
|
33
|
-
version_requirements: !ruby/object:Gem::Requirement
|
34
|
-
requirements:
|
35
|
-
- - ">="
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: "0"
|
30
|
+
version: 1.7.0
|
38
31
|
version:
|
39
32
|
- !ruby/object:Gem::Dependency
|
40
33
|
name: eventmachine
|
@@ -51,6 +44,9 @@ email:
|
|
51
44
|
- blaine@twitter.com
|
52
45
|
- chris@ozmm.org
|
53
46
|
- abdulrahman@advany.com
|
47
|
+
- starlingmq@groups.google.com
|
48
|
+
- harmaarts@gmail.com
|
49
|
+
- gaffneyc@gmail.com
|
54
50
|
executables:
|
55
51
|
- starling
|
56
52
|
- starling_top
|
@@ -61,21 +57,26 @@ extra_rdoc_files:
|
|
61
57
|
- CHANGELOG
|
62
58
|
- LICENSE
|
63
59
|
files:
|
64
|
-
-
|
65
|
-
-
|
60
|
+
- bin/starling
|
61
|
+
- bin/starling_top
|
66
62
|
- CHANGELOG
|
67
|
-
-
|
63
|
+
- etc/sample-config.yml
|
64
|
+
- etc/starling.redhat
|
65
|
+
- etc/starling.ubuntu
|
68
66
|
- lib/starling/handler.rb
|
69
67
|
- lib/starling/persistent_queue.rb
|
70
68
|
- lib/starling/queue_collection.rb
|
71
|
-
- lib/starling/server_runner.rb
|
72
69
|
- lib/starling/server.rb
|
70
|
+
- lib/starling/server_runner.rb
|
73
71
|
- lib/starling.rb
|
74
|
-
-
|
75
|
-
-
|
76
|
-
-
|
72
|
+
- LICENSE
|
73
|
+
- Rakefile
|
74
|
+
- README.rdoc
|
75
|
+
- spec/starling_server_spec.rb
|
77
76
|
has_rdoc: true
|
78
77
|
homepage: http://github.com/starling/starling/
|
78
|
+
licenses: []
|
79
|
+
|
79
80
|
post_install_message:
|
80
81
|
rdoc_options:
|
81
82
|
- --quiet
|
@@ -104,9 +105,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
105
|
requirements: []
|
105
106
|
|
106
107
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.
|
108
|
+
rubygems_version: 1.3.5
|
108
109
|
signing_key:
|
109
|
-
specification_version:
|
110
|
+
specification_version: 3
|
110
111
|
summary: Starling is a lightweight, transactional, distributed queue server
|
111
|
-
test_files:
|
112
|
-
|
112
|
+
test_files: []
|
113
|
+
|