starling-starling 0.9.7.10 → 0.9.8.200810061510
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +17 -0
- data/Rakefile +3 -2
- data/etc/sample-config.yml +9 -0
- data/etc/starling.redhat +50 -47
- data/lib/starling.rb +65 -1
- data/lib/starling/handler.rb +35 -24
- data/lib/starling/persistent_queue.rb +5 -0
- data/lib/starling/queue_collection.rb +7 -1
- data/lib/starling/server.rb +21 -9
- data/lib/starling/server_runner.rb +18 -8
- data/{test/test_starling_server.rb → spec/starling_server_spec.rb} +45 -34
- metadata +5 -13
data/CHANGELOG
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
== 0.9.9
|
2
|
+
* remove dependency on SyslogLogger so that starling works on windows.
|
3
|
+
* fix config file loading so relative paths are expanded properly <jacob@jacobatzen.dk>
|
4
|
+
* clean up redhat init.d script <gaffneyc@gmail.com>
|
5
|
+
|
6
|
+
== 0.9.8
|
7
|
+
* add fix to enable relative paths <david@motorator.com>
|
8
|
+
* fix tests so they don't run 10 times due to a stupid bug with how the server is forked <seth@mojodna.net>
|
9
|
+
* fix some other tests <romeda@gmail.com>
|
10
|
+
* fix some error messages <romeda@gmail.com>
|
11
|
+
* probably some other things <romeda@gmail.com>
|
12
|
+
|
13
|
+
== 0.9.7.9
|
14
|
+
* properly complain if the spool directory isn't writable <seth@mojodna.net>
|
15
|
+
* assume group and user privileges in a working order <seth@mojodna.net>
|
16
|
+
* support string user / group names in addition to uid/gids <seth@mojodna.net>
|
17
|
+
|
1
18
|
== 0.9.7.7
|
2
19
|
* added init.d scripts for redhat and ubuntu by Mike Perham <mperham@gmail.com>
|
3
20
|
* fixed dependencies for SyslogLogger, eventmachine and memcache-client by Mike Perham <mperham@gmail.com>
|
data/Rakefile
CHANGED
@@ -2,6 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'rake/rdoctask'
|
3
3
|
require 'spec/rake/spectask'
|
4
4
|
|
5
|
+
task :default => :spec
|
6
|
+
|
5
7
|
task :install do
|
6
8
|
sh %{gem build starling.gemspec}
|
7
9
|
sh %{sudo gem install starling-*.gem}
|
@@ -9,7 +11,7 @@ end
|
|
9
11
|
|
10
12
|
Spec::Rake::SpecTask.new do |t|
|
11
13
|
t.ruby_opts = ['-rtest/unit']
|
12
|
-
t.spec_files = FileList['
|
14
|
+
t.spec_files = FileList['spec/*_spec.rb']
|
13
15
|
t.fail_on_error = true
|
14
16
|
end
|
15
17
|
|
@@ -17,5 +19,4 @@ Rake::RDocTask.new do |rd|
|
|
17
19
|
rd.main = "README.rdoc"
|
18
20
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
19
21
|
rd.rdoc_dir = 'doc'
|
20
|
-
# rd.options = spec.rdoc_options
|
21
22
|
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/lib/starling.rb
CHANGED
@@ -3,18 +3,60 @@ 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
|
17
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
|
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
|
+
# Acquires the mutex for the entire duration of the call
|
47
|
+
# since unrelated calls to #get_server_for_key might be
|
48
|
+
# adversely affected by the non_random result.
|
49
|
+
def with_servers(my_servers = @servers.dup)
|
50
|
+
return unless block_given?
|
51
|
+
with_lock do
|
52
|
+
my_servers.each do |server|
|
53
|
+
@force_server = server
|
54
|
+
yield
|
55
|
+
end
|
56
|
+
@force_server = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
18
60
|
##
|
19
61
|
# insert +value+ into +queue+.
|
20
62
|
#
|
@@ -90,6 +132,7 @@ class Starling < MemCache
|
|
90
132
|
raise ArgumentError, "illegal character in key #{key.inspect}" if key =~ /\s/
|
91
133
|
raise ArgumentError, "key too long #{key.inspect}" if key.length > 250
|
92
134
|
raise MemCacheError, "No servers available" if @servers.empty?
|
135
|
+
return @force_server if @force_server
|
93
136
|
|
94
137
|
bukkits = @buckets.dup
|
95
138
|
bukkits.nitems.times do |try|
|
@@ -102,3 +145,24 @@ class Starling < MemCache
|
|
102
145
|
raise MemCacheError, "No servers available (all dead)"
|
103
146
|
end
|
104
147
|
end
|
148
|
+
|
149
|
+
|
150
|
+
class MemCache
|
151
|
+
|
152
|
+
protected
|
153
|
+
|
154
|
+
##
|
155
|
+
# Ensure that everything within the given block is executed
|
156
|
+
# within the locked mutex if this client is multithreaded.
|
157
|
+
# If the client isn't multithreaded, the block is simply executed.
|
158
|
+
def with_lock
|
159
|
+
return unless block_given?
|
160
|
+
begin
|
161
|
+
@mutex.lock if @multithread
|
162
|
+
yield
|
163
|
+
ensure
|
164
|
+
@mutex.unlock if @multithread
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
data/lib/starling/handler.rb
CHANGED
@@ -22,33 +22,37 @@ 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
|
-
STAT queue_%s_age %d\n".freeze
|
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
|
55
|
+
STAT queue_%s_age %d\r\n".freeze
|
52
56
|
|
53
57
|
SHUTDOWN_COMMAND = /\Ashutdown\r\n/m
|
54
58
|
|
@@ -108,7 +112,6 @@ STAT queue_%s_age %d\n".freeze
|
|
108
112
|
@data_buf = data
|
109
113
|
return
|
110
114
|
end
|
111
|
-
|
112
115
|
case data
|
113
116
|
when SET_COMMAND
|
114
117
|
@server.stats[:set_requests] += 1
|
@@ -121,6 +124,8 @@ STAT queue_%s_age %d\n".freeze
|
|
121
124
|
when SHUTDOWN_COMMAND
|
122
125
|
# no point in responding, they'll never get it.
|
123
126
|
Runner::shutdown
|
127
|
+
when DELETE_COMMAND
|
128
|
+
delete $1
|
124
129
|
else
|
125
130
|
logger.warn "Unknown command: #{data}."
|
126
131
|
respond ERR_UNKNOWN_COMMAND
|
@@ -136,6 +141,12 @@ STAT queue_%s_age %d\n".freeze
|
|
136
141
|
end
|
137
142
|
|
138
143
|
private
|
144
|
+
|
145
|
+
def delete(queue)
|
146
|
+
@queue_collection.delete(queue)
|
147
|
+
respond DELETE_RESPONSE
|
148
|
+
end
|
149
|
+
|
139
150
|
def respond(str, *args)
|
140
151
|
response = sprintf(str, *args)
|
141
152
|
@server.stats[:bytes_written] += response.length
|
@@ -15,7 +15,7 @@ module StarlingServer
|
|
15
15
|
|
16
16
|
def initialize(path)
|
17
17
|
unless File.directory?(path) && File.writable?(path)
|
18
|
-
raise InaccessibleQueuePath.new("#{path} must exist and be writable by #{Etc.getpwuid(Process.uid).name}.")
|
18
|
+
raise InaccessibleQueuePath.new("'#{path}' must exist and be read-writable by #{Etc.getpwuid(Process.uid).name}.")
|
19
19
|
end
|
20
20
|
|
21
21
|
@shutdown_mutex = Mutex.new
|
@@ -59,6 +59,12 @@ module StarlingServer
|
|
59
59
|
@stats[:current_bytes] -= result.size
|
60
60
|
result
|
61
61
|
end
|
62
|
+
|
63
|
+
def delete(key)
|
64
|
+
queue = @queues.delete(key)
|
65
|
+
return if queue.nil?
|
66
|
+
queue.purge
|
67
|
+
end
|
62
68
|
|
63
69
|
##
|
64
70
|
# Returns all active queues.
|
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.9.
|
13
|
+
VERSION = "0.9.8"
|
15
14
|
|
16
15
|
class Base
|
17
16
|
attr_reader :logger
|
@@ -68,14 +67,27 @@ 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
|
77
78
|
|
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
|
84
|
+
|
85
|
+
begin
|
86
|
+
@opts[:queue] = QueueCollection.new(@opts[:path])
|
87
|
+
rescue InaccessibleQueuePath => e
|
88
|
+
puts "Error: #{e.message}"
|
89
|
+
exit 1
|
90
|
+
end
|
79
91
|
@@logger.level = @opts[:log_level] || Logger::ERROR
|
80
92
|
|
81
93
|
@@logger.info "Starling STARTUP on #{@opts[:host]}:#{@opts[:port]}"
|
@@ -40,6 +40,11 @@ module StarlingServer
|
|
40
40
|
when "queue_path" then key = "path"
|
41
41
|
when "log_file" then key = "logger"
|
42
42
|
end
|
43
|
+
|
44
|
+
if %w(logger path pid_file).include?(key)
|
45
|
+
value = File.expand_path(value)
|
46
|
+
end
|
47
|
+
|
43
48
|
options[key.to_sym] = value
|
44
49
|
|
45
50
|
if options[:log_level].instance_of?(String)
|
@@ -51,11 +56,11 @@ module StarlingServer
|
|
51
56
|
def parse_options
|
52
57
|
self.options = { :host => '127.0.0.1',
|
53
58
|
:port => 22122,
|
54
|
-
:path => File.join(
|
59
|
+
:path => File.join('', 'var', 'spool', 'starling'),
|
55
60
|
:log_level => Logger::INFO,
|
56
61
|
:daemonize => false,
|
57
62
|
:timeout => 0,
|
58
|
-
:pid_file => File.join(
|
63
|
+
:pid_file => File.join('', 'var', 'run', 'starling.pid') }
|
59
64
|
|
60
65
|
OptionParser.new do |opts|
|
61
66
|
opts.summary_width = 25
|
@@ -76,7 +81,7 @@ module StarlingServer
|
|
76
81
|
opts.on("-q", "--queue_path PATH",
|
77
82
|
:REQUIRED,
|
78
83
|
"Path to store Starling queue logs", "(default: #{options[:path]})") do |queue_path|
|
79
|
-
options[:path] = queue_path
|
84
|
+
options[:path] = File.expand_path(queue_path)
|
80
85
|
end
|
81
86
|
|
82
87
|
opts.separator ""; opts.separator "Network:"
|
@@ -96,7 +101,7 @@ module StarlingServer
|
|
96
101
|
end
|
97
102
|
|
98
103
|
opts.on("-PFILE", "--pid FILENAME", "save PID in FILENAME when using -d option.", "(default: #{options[:pid_file]})") do |pid_file|
|
99
|
-
options[:pid_file] = pid_file
|
104
|
+
options[:pid_file] = File.expand_path(pid_file)
|
100
105
|
end
|
101
106
|
|
102
107
|
opts.on("-u", "--user USER", "User to run as") do |user|
|
@@ -110,11 +115,16 @@ module StarlingServer
|
|
110
115
|
opts.separator ""; opts.separator "Logging:"
|
111
116
|
|
112
117
|
opts.on("-L", "--log [FILE]", "Path to print debugging information.") do |log_path|
|
113
|
-
options[:logger] = log_path
|
118
|
+
options[:logger] = File.expand_path(log_path)
|
114
119
|
end
|
115
120
|
|
116
|
-
|
117
|
-
|
121
|
+
begin
|
122
|
+
require 'syslog_logger'
|
123
|
+
|
124
|
+
opts.on("-l", "--syslog CHANNEL", "Write logs to the syslog instead of a log file.") do |channel|
|
125
|
+
options[:syslog_channel] = channel
|
126
|
+
end
|
127
|
+
rescue LoadError
|
118
128
|
end
|
119
129
|
|
120
130
|
opts.on("-v", "Increase logging verbosity (may be used multiple times).") do
|
@@ -216,7 +226,7 @@ module StarlingServer
|
|
216
226
|
safefork and exit
|
217
227
|
|
218
228
|
unless sess_id = Process.setsid
|
219
|
-
raise "Couldn't
|
229
|
+
raise "Couldn't detach from controlling terminal."
|
220
230
|
end
|
221
231
|
|
222
232
|
trap 'SIGHUP', 'IGNORE'
|
@@ -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
|
|
@@ -22,7 +23,7 @@ def safely_fork(&block)
|
|
22
23
|
while blocking
|
23
24
|
sleep 0.1
|
24
25
|
end
|
25
|
-
|
26
|
+
|
26
27
|
pid
|
27
28
|
end
|
28
29
|
|
@@ -41,12 +42,17 @@ describe "StarlingServer" do
|
|
41
42
|
:path => @tmp_path,
|
42
43
|
:logger => Logger.new(STDERR),
|
43
44
|
:log_level => Logger::FATAL)
|
44
|
-
Signal.trap("INT") {
|
45
|
+
Signal.trap("INT") {
|
46
|
+
server.stop
|
47
|
+
exit
|
48
|
+
}
|
49
|
+
|
45
50
|
Process.kill("USR1", Process.ppid)
|
46
51
|
server.run
|
47
52
|
end
|
48
53
|
|
49
54
|
@client = MemCache.new('127.0.0.1:22133')
|
55
|
+
|
50
56
|
end
|
51
57
|
|
52
58
|
it "should test if temp_path exists and is writeable" do
|
@@ -62,6 +68,14 @@ describe "StarlingServer" do
|
|
62
68
|
@client.get('test_set_and_get_one_entry').should eql(v)
|
63
69
|
end
|
64
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
|
65
79
|
|
66
80
|
it "should expire entries" do
|
67
81
|
v = rand((2**32)-1)
|
@@ -143,45 +157,42 @@ describe "StarlingServer" do
|
|
143
157
|
# handle more than 1024 connections.
|
144
158
|
|
145
159
|
unless IO::popen("uname").read.chomp == "Linux"
|
146
|
-
|
147
|
-
skip = true
|
160
|
+
pending "skipping epoll test: not on Linux"
|
148
161
|
end
|
162
|
+
|
149
163
|
fd_limit = IO::popen("bash -c 'ulimit -n'").read.chomp.to_i
|
150
164
|
unless fd_limit > 1024
|
151
|
-
|
152
|
-
skip = true
|
165
|
+
pending "skipping epoll test: 'ulimit -n' = #{fd_limit}, need > 1024"
|
153
166
|
end
|
154
167
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
unused_sockets << TCPSocket.new("127.0.0.1", 22133)
|
165
|
-
end
|
166
|
-
Process.kill("USR1", Process.ppid)
|
167
|
-
sleep 90
|
168
|
+
v = rand(2**32 - 1)
|
169
|
+
@client.set('test_epoll', v)
|
170
|
+
|
171
|
+
# we can't open 1024 connections to memcache from within this process,
|
172
|
+
# because we will hit ruby's 1024 fd limit ourselves!
|
173
|
+
pid1 = safely_fork do
|
174
|
+
unused_sockets = []
|
175
|
+
600.times do
|
176
|
+
unused_sockets << TCPSocket.new("127.0.0.1", 22133)
|
168
177
|
end
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
178
|
+
Process.kill("USR1", Process.ppid)
|
179
|
+
sleep 90
|
180
|
+
end
|
181
|
+
pid2 = safely_fork do
|
182
|
+
unused_sockets = []
|
183
|
+
600.times do
|
184
|
+
unused_sockets << TCPSocket.new("127.0.0.1", 22133)
|
176
185
|
end
|
186
|
+
Process.kill("USR1", Process.ppid)
|
187
|
+
sleep 90
|
188
|
+
end
|
177
189
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
end
|
190
|
+
begin
|
191
|
+
client = MemCache.new('127.0.0.1:22133')
|
192
|
+
client.get('test_epoll').should eql(v)
|
193
|
+
ensure
|
194
|
+
Process.kill("TERM", pid1)
|
195
|
+
Process.kill("TERM", pid2)
|
185
196
|
end
|
186
197
|
end
|
187
198
|
|
@@ -202,4 +213,4 @@ describe "StarlingServer" do
|
|
202
213
|
@client.reset
|
203
214
|
FileUtils.rm(Dir.glob(File.join(@tmp_path, '*')))
|
204
215
|
end
|
205
|
-
end
|
216
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: starling-starling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.8.200810061510
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blaine Cook
|
@@ -13,20 +13,11 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2008-
|
16
|
+
date: 2008-10-09 00:00:00 -07:00
|
17
17
|
default_executable:
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
|
-
name:
|
21
|
-
version_requirement:
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: "0"
|
27
|
-
version:
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: SyslogLogger
|
20
|
+
name: memcache-client
|
30
21
|
version_requirement:
|
31
22
|
version_requirements: !ruby/object:Gem::Requirement
|
32
23
|
requirements:
|
@@ -70,6 +61,7 @@ files:
|
|
70
61
|
- lib/starling.rb
|
71
62
|
- etc/starling.redhat
|
72
63
|
- etc/starling.ubuntu
|
64
|
+
- etc/sample-config.yml
|
73
65
|
has_rdoc: true
|
74
66
|
homepage: http://github.com/starling/starling/
|
75
67
|
post_install_message:
|
@@ -105,4 +97,4 @@ signing_key:
|
|
105
97
|
specification_version: 2
|
106
98
|
summary: Starling is a lightweight, transactional, distributed queue server
|
107
99
|
test_files:
|
108
|
-
-
|
100
|
+
- spec/starling_server_spec.rb
|