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 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
- This fork of the Starling source is hosted at GitHub and can be found at:
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, 1 buckets, ns: nil, ro: false
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 fiveruns memcache-client
70
+ = Using memcache-client
71
71
 
72
- memcache-client from fiveruns has a couple of fixed added like supporting failover and retry on failure.
72
+ memcache-client is now maintained by Mike Perham (http://www.mikeperham.com/)
73
73
 
74
- This fork of the memcache-client source is hosted at GitHub and can be found at:
74
+ He is the current maintainer of the gem which is hosted at GitHub and can be found at:
75
75
 
76
- http://github.com/fiveruns/memcache-client/tree/master
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 fiveruns-memcache-client
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/rdoctask'
3
- require 'spec/rake/spectask'
4
-
5
- task :default => :spec
2
+ require 'rake'
6
3
 
7
- task :install do
8
- sh %{gem build starling.gemspec}
9
- sh %{sudo gem install starling-*.gem}
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
- Spec::Rake::SpecTask.new do |t|
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
- #determine where the 'pidof' executable is located
9
- if [ -e /bin/pidof ]; then
10
- PIDOF="/bin/pidof"
11
- elif [ -e /sbin/pidof ]; then
12
- PIDOF="/sbin/pidof"
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
- pid=`$PIDOF $PROGNAME`
31
- if [ "$pid" != "" ]; then
32
- echo "$PROGDIR$PROGNAME already running: $pid"
33
- else
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
- pid=`$PIDOF $PROGNAME`
42
- if [ "$pid" != "" ]; then
43
- echo "Stopping $PROGDIR$PROGNAME: $pid"
44
- kill $pid
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
- start
53
- ;;
54
- stop)
55
- stop
56
- ;;
57
- restart)
58
- stop
59
- sleep 3
60
- start
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
@@ -9,7 +9,7 @@
9
9
  # Description: The Starling distributed, transactional queue server
10
10
  ### END INIT INFO
11
11
  # Author: Twitter
12
- # Version: 0.9.7.7
12
+ # Version: 0.10.0
13
13
 
14
14
  set -e
15
15
 
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 = super(*args)
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 @servers.empty?
93
-
94
- bukkits = @buckets.dup
95
- bukkits.nitems.times do |try|
96
- n = rand(bukkits.nitems)
97
- server = bukkits[n]
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
- bukkits.delete_at(n)
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
@@ -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
@@ -83,6 +83,11 @@ module StarlingServer
83
83
  @trx = nil
84
84
  @not_trx.close
85
85
  end
86
+
87
+ def purge
88
+ close
89
+ File.delete(log_path)
90
+ end
86
91
 
87
92
  private
88
93
 
@@ -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.
@@ -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.8"
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
- @@logger = case @opts[:logger]
72
- when IO, String; Logger.new(@opts[:logger])
73
- when Logger; @opts[:logger]
74
- else; Logger.new(STDERR)
75
- end
76
- @@logger = SyslogLogger.new(@opts[:syslog_channel]) if @opts[:syslog_channel]
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.open(filename))['starling'].each do |key, value|
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
- opts.on("-l", "--syslog CHANNEL", "Write logs to the syslog instead of a log file.") do |channel|
117
- options[:syslog_channel] = channel
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.egid = options[:group] if options[:group]
161
- Process.euid = options[:user] if options[:user]
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
- assert_kind_of Hash, stats
117
- assert stats.has_key?('127.0.0.1:22133')
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
- response = @client.add('blah', 1)
133
- response.should eql("CLIENT_ERROR bad command line format\r\n")
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.9.8
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: 2008-08-26 00:00:00 -07:00
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: "0"
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
- - README.rdoc
65
- - LICENSE
60
+ - bin/starling
61
+ - bin/starling_top
66
62
  - CHANGELOG
67
- - Rakefile
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
- - etc/starling.redhat
75
- - etc/starling.ubuntu
76
- - etc/sample-config.yml
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.2.0
108
+ rubygems_version: 1.3.5
108
109
  signing_key:
109
- specification_version: 2
110
+ specification_version: 3
110
111
  summary: Starling is a lightweight, transactional, distributed queue server
111
- test_files:
112
- - spec/starling_server_spec.rb
112
+ test_files: []
113
+