nutcracker-web 0.0.11 → 0.0.16

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9556cc53f5173af776c4137acabe20ec300a5a53
4
- data.tar.gz: b8592b44ae6f60b1f13c9f82ece5ea7c44be10fb
2
+ SHA256:
3
+ metadata.gz: 5cfaf35ebfe172724c2abb8d91ac273112eaec29b00cecc9e4885af424ad17e9
4
+ data.tar.gz: 4510246fea3f44312311b80b8029d193599f045c888eaed8721ae6d8b71f2b0e
5
5
  SHA512:
6
- metadata.gz: 5dce95488c0bbc7cf78556c27b02925cc8be10b6c769e0a0438651fe7c140882164248e115c4ae34b8505c7bcc6d72e4bb35dc01ca9dae9b440cbcba9d738d2f
7
- data.tar.gz: a25465a6cae3856b36073e968f243c38e7606585d5a8d9dd334c513fbdd5f3170b9e56e330e3907ab011d5d363811f60327f67e4f6b0c77b84f3f65a0babca4b
6
+ metadata.gz: fc58f9eca3e31f8ffdb9ecbf52bfea5cfc580c4f2a61f2c5ff148ee301cf9193f563e00cc51160d54616b0ea4af169c8751f821761714ad25bc4d67920851d8c
7
+ data.tar.gz: 8de6d844c4fc9355ed27a483211c0ad93e3e364c88b7497d65598e09dcd19e485cbf2b891ca38a1cf0e703ed2c6e436145cd5f429f8981e9a1a38155a3ad114d
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gem 'thin'
6
6
  gem 'sprockets'
7
7
  gem 'coffee-script'
8
8
  gem 'eco'
9
- gem 'json'
10
9
  gem 'uglifier'
11
10
  gem 'nutcracker', ">=0.4.1.20"
11
+ gem "rack", ">= 2.0.8"
12
+ gem 'rake'
@@ -4,38 +4,43 @@ GEM
4
4
  coffee-script (2.4.1)
5
5
  coffee-script-source
6
6
  execjs
7
- coffee-script-source (1.9.1.1)
8
- daemons (1.2.3)
7
+ coffee-script-source (1.12.2)
8
+ concurrent-ruby (1.0.5)
9
+ daemons (1.2.6)
9
10
  eco (1.0.0)
10
11
  coffee-script
11
12
  eco-source
12
13
  execjs
13
14
  eco-source (1.1.0.rc.1)
14
- eventmachine (1.0.8)
15
- execjs (2.6.0)
16
- haml (4.0.7)
15
+ eventmachine (1.2.7)
16
+ execjs (2.7.0)
17
+ haml (5.0.4)
18
+ temple (>= 0.8.0)
17
19
  tilt
18
- json (1.8.3)
19
- nutcracker (0.4.1.20)
20
+ mustermann (1.0.3)
21
+ nutcracker (0.4.1.22)
20
22
  redis
21
- rack (1.6.4)
22
- rack-protection (1.5.3)
23
+ rack (2.2.2)
24
+ rack-protection (2.0.4)
23
25
  rack
24
- redis (3.3.2)
25
- sinatra (1.4.6)
26
- rack (~> 1.4)
27
- rack-protection (~> 1.4)
28
- tilt (>= 1.3, < 3)
29
- sprockets (3.3.5)
26
+ rake (13.0.1)
27
+ redis (4.0.2)
28
+ sinatra (2.0.4)
29
+ mustermann (~> 1.0)
30
+ rack (~> 2.0)
31
+ rack-protection (= 2.0.4)
32
+ tilt (~> 2.0)
33
+ sprockets (3.7.2)
34
+ concurrent-ruby (~> 1.0)
30
35
  rack (> 1, < 3)
31
- thin (1.6.4)
36
+ temple (0.8.0)
37
+ thin (1.7.2)
32
38
  daemons (~> 1.0, >= 1.0.9)
33
39
  eventmachine (~> 1.0, >= 1.0.4)
34
- rack (~> 1.0)
35
- tilt (2.0.1)
36
- uglifier (2.7.2)
37
- execjs (>= 0.3.0)
38
- json (>= 1.8.0)
40
+ rack (>= 1, < 3)
41
+ tilt (2.0.8)
42
+ uglifier (4.1.19)
43
+ execjs (>= 0.3.0, < 3)
39
44
 
40
45
  PLATFORMS
41
46
  ruby
@@ -44,12 +49,13 @@ DEPENDENCIES
44
49
  coffee-script
45
50
  eco
46
51
  haml
47
- json
48
52
  nutcracker (>= 0.4.1.20)
53
+ rack (>= 2.0.8)
54
+ rake
49
55
  sinatra
50
56
  sprockets
51
57
  thin
52
58
  uglifier
53
59
 
54
60
  BUNDLED WITH
55
- 1.11.2
61
+ 1.17.2
data/README.md CHANGED
@@ -21,12 +21,15 @@ Usage: nutcracker-web [web-options] -- [nutcracker-options]
21
21
 
22
22
  [web-options]
23
23
 
24
- -s, --stats-port PORT Nutcracker stats port - 22222
24
+ -u, --stats-uri URI Nutcracker stats uri, default is tcp://localhost:22222
25
25
  -c, --config FILE Nutcracker cluster config file
26
26
  -p, --port PORT Web interface listening port
27
27
  -b, --backend BACKEND Web server to use ( needs to be Rack compliant )
28
+ -x, --context CONTEXT Web Interface URL context, default /
28
29
  -d, --daemonize run in background
29
30
  -l, --launch launch Nutcracker instance as well
31
+ -s, --max-memory SIZE manually specify max memory for every redis node ( Use it for elastic cache )
32
+ -v, --version Print version and exit
30
33
  -i, --pid FILE pid file
31
34
 
32
35
  [nutcracker-options]
@@ -36,7 +39,7 @@ Usage: nutcracker-web [web-options] -- [nutcracker-options]
36
39
  -t, --test-conf : test configuration for syntax errors and exit
37
40
  -d, --daemonize : run as a daemon
38
41
  -D, --describe-stats : print stats description and exit
39
- -v, --verbosity=N : set logging level (default: 5, min: 0, max: 11)
42
+ -v, --verbose=N : set logging level (default: 5, min: 0, max: 11)
40
43
  -o, --output=S : set logging file (default: stderr)
41
44
  -c, --conf-file=S : set configuration file (default: conf/nutcracker.yml)
42
45
  -s, --stats-port=N : set stats monitoring port (default: 22222)
data/Rakefile CHANGED
@@ -29,6 +29,7 @@ task :compile do
29
29
  end
30
30
  end
31
31
 
32
+ desc "Build new gem"
32
33
  task :build => [:compile] do
33
34
  Gem::PackageTask.new(eval File.read 'nutcracker-web.gemspec') do |pkg|
34
35
  pkg.need_zip = false
@@ -3,6 +3,7 @@ $:.unshift File.expand_path('../../lib',__FILE__)
3
3
 
4
4
  require 'nutcracker'
5
5
  require 'nutcracker/web'
6
+ require 'nutcracker/web/version'
6
7
  require 'optparse'
7
8
  require 'fileutils'
8
9
  require 'socket'
@@ -34,6 +35,10 @@ OptionParser.new do |opts|
34
35
  opts.on("-b","--backend BACKEND", "Web server to use ( needs to be Rack compliant )") do |v|
35
36
  options[:server] = v
36
37
  end
38
+
39
+ opts.on("-x", "--context CONTEXT", "Web Interface URL context, default /") do |v|
40
+ options[:context] = "/#{v}".squeeze("/")
41
+ end
37
42
 
38
43
  opts.on("-d", "--daemonize","run in background") do
39
44
  options[:daemonize] = true
@@ -47,6 +52,10 @@ OptionParser.new do |opts|
47
52
  options[:max_memory] = v
48
53
  end
49
54
 
55
+ opts.on("-v", "--version", "Print version and exit") do
56
+ abort "Nutcracker-Web, Ver. #{Nutcracker::Web::VERSION}"
57
+ end
58
+
50
59
  opts.on("-i","--pid FILE","pid file") do |v|
51
60
  options[:pid] = v
52
61
  options[:nutcracker_pid] = v + ".nutcracker"
@@ -2,27 +2,31 @@ require "rack"
2
2
 
3
3
  module Nutcracker
4
4
  module Web
5
- def self.start(nutcracker, options = {})
5
+ def self.start(nutcracker, o = {})
6
6
  @thread = Thread.new do
7
7
  Thread.current.abort_on_exception=true
8
+
9
+ app = Rack::URLMap.new(o.fetch(:context,"/") =>
10
+ App.new(nutcracker, o.fetch(:external_servers,[])))
11
+
8
12
  Rack::Server.start(
9
13
  {
10
- :app => App.new(nutcracker, options[:external_servers] || []),
14
+ :app => app,
11
15
  :environment => 'production',
12
16
  :pid => nil,
13
17
  :Port => 9292,
14
18
  :Host => '0.0.0.0',
15
19
  :AccessLog => []
16
- }.merge( options )
20
+ }.merge(o)
17
21
  )
18
22
  end
19
23
  self
20
24
  end
21
-
25
+
22
26
  def self.join
23
27
  @thread.join
24
28
  end
25
-
29
+
26
30
  def self.stop
27
31
  @thread.kill
28
32
  end
@@ -4,6 +4,9 @@ require 'tilt/haml'
4
4
  require 'haml'
5
5
  require 'sinatra'
6
6
  require 'json'
7
+ require 'thread'
8
+ require 'socket'
9
+
7
10
 
8
11
  module Nutcracker
9
12
  module Web
@@ -21,11 +24,23 @@ module Nutcracker
21
24
  haml :index
22
25
  end
23
26
 
27
+ get '/status' do
28
+ @nutcracker.
29
+ config.
30
+ values.
31
+ map {|x| x["servers"] + [x["listen"]]}.
32
+ flatten.
33
+ map {|x| x.split(":")}.
34
+ map {|host, port| Thread.new {TCPSocket.new(host,port).close.nil? rescue false}}.map(&:value).
35
+ all?.
36
+ tap {|x| status(x ? 200 : 401)}
37
+ end
38
+
24
39
  get '/overview.json' do
25
40
  content_type :json
26
41
  overview.to_json
27
42
  end
28
-
43
+
29
44
  def self.assets
30
45
  require 'sprockets'
31
46
  Sprockets::Environment.new { |env|
@@ -34,18 +49,18 @@ module Nutcracker
34
49
  }
35
50
  }
36
51
  end
37
-
52
+
38
53
  private
39
-
54
+
40
55
  def overview
41
56
  JSON.parse(@nutcracker.overview.to_json).tap do |internal|
42
57
  internal["clusters"] += overview_from_external_servers["clusters"]
43
58
  end
44
59
  end
45
-
60
+
46
61
  def overview_from_external_servers
47
62
  {"clusters" => []}.tap do |data|
48
- Queue.new.tap do |q|
63
+ Queue.new.tap do |q|
49
64
  @external_servers.map do |server|
50
65
  Thread.new { q.push JSON.parse(open("http://#{server}/overview.json").read) }
51
66
  end.each(&:join)
@@ -53,7 +68,7 @@ module Nutcracker
53
68
  end # queue
54
69
  end # data
55
70
  end # def
56
-
71
+
57
72
  end
58
73
  end
59
74
  end
@@ -64,7 +79,7 @@ __END__
64
79
  %html
65
80
  %head
66
81
  %title Nutcracker-Web
67
- %script(type='text/javascript' src='http://www.google.com/jsapi')
82
+ %script(type='text/javascript' src='https://www.google.com/jsapi')
68
83
  %script(type='text/javascript' src='assets/application.js')
69
84
  %link(rel='stylesheet' href='assets/application.css')
70
85
  %body
@@ -1,5 +1,5 @@
1
1
  module Nutcracker
2
2
  module Web
3
- VERSION="0.0.11"
3
+ VERSION="0.0.16"
4
4
  end
5
5
  end
@@ -11,7 +11,8 @@
11
11
  *
12
12
  * Date: 2013-05-30T21:25Z
13
13
  */
14
- !function(t,e){function n(t){var e=t.length,n=ot.type(t);return ot.isWindow(t)?!1:1===t.nodeType&&e?!0:"array"===n||"function"!==n&&(0===e||"number"==typeof e&&e>0&&e-1 in t)}function r(t){var e=dt[t]={};return ot.each(t.match(at)||[],function(t,n){e[n]=!0}),e}function i(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=ot.expando+Math.random()}function o(t,n,r){var i;if(r===e&&1===t.nodeType)if(i="data-"+n.replace(yt,"-$1").toLowerCase(),r=t.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:vt.test(r)?JSON.parse(r):r}catch(o){}mt.set(t,n,r)}else r=e;return r}function s(){return!0}function a(){return!1}function u(){try{return U.activeElement}catch(t){}}function l(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}function c(t,e,n){if(ot.isFunction(e))return ot.grep(t,function(t,r){return!!e.call(t,r,t)!==n});if(e.nodeType)return ot.grep(t,function(t){return t===e!==n});if("string"==typeof e){if($t.test(e))return ot.filter(e,t,n);e=ot.filter(e,t)}return ot.grep(t,function(t){return et.call(e,t)>=0!==n})}function h(t,e){return ot.nodeName(t,"table")&&ot.nodeName(1===e.nodeType?e:e.firstChild,"tr")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}function f(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function p(t){var e=zt.exec(t.type);return e?t.type=e[1]:t.removeAttribute("type"),t}function d(t,e){for(var n=t.length,r=0;n>r;r++)gt.set(t[r],"globalEval",!e||gt.get(e[r],"globalEval"))}function m(t,e){var n,r,i,o,s,a,u,l;if(1===e.nodeType){if(gt.hasData(t)&&(o=gt.access(t),s=gt.set(e,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)ot.event.add(e,i,l[i][n])}mt.hasData(t)&&(a=mt.access(t),u=ot.extend({},a),mt.set(e,u))}}function g(t,n){var r=t.getElementsByTagName?t.getElementsByTagName(n||"*"):t.querySelectorAll?t.querySelectorAll(n||"*"):[];return n===e||n&&ot.nodeName(t,n)?ot.merge([t],r):r}function v(t,e){var n=e.nodeName.toLowerCase();"input"===n&&Pt.test(t.type)?e.checked=t.checked:("input"===n||"textarea"===n)&&(e.defaultValue=t.defaultValue)}function y(t,e){if(e in t)return e;for(var n=e.charAt(0).toUpperCase()+e.slice(1),r=e,i=Zt.length;i--;)if(e=Zt[i]+n,e in t)return e;return r}function b(t,e){return t=e||t,"none"===ot.css(t,"display")||!ot.contains(t.ownerDocument,t)}function w(e){return t.getComputedStyle(e,null)}function x(t,e){for(var n,r,i,o=[],s=0,a=t.length;a>s;s++)r=t[s],r.style&&(o[s]=gt.get(r,"olddisplay"),n=r.style.display,e?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&b(r)&&(o[s]=gt.access(r,"olddisplay",_(r.nodeName)))):o[s]||(i=b(r),(n&&"none"!==n||!i)&>.set(r,"olddisplay",i?n:ot.css(r,"display"))));for(s=0;a>s;s++)r=t[s],r.style&&(e&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=e?o[s]||"":"none"));return t}function C(t,e,n){var r=Jt.exec(e);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):e}function k(t,e,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===e?1:0,s=0;4>o;o+=2)"margin"===n&&(s+=ot.css(t,n+Kt[o],!0,i)),r?("content"===n&&(s-=ot.css(t,"padding"+Kt[o],!0,i)),"margin"!==n&&(s-=ot.css(t,"border"+Kt[o]+"Width",!0,i))):(s+=ot.css(t,"padding"+Kt[o],!0,i),"padding"!==n&&(s+=ot.css(t,"border"+Kt[o]+"Width",!0,i)));return s}function T(t,e,n){var r=!0,i="width"===e?t.offsetWidth:t.offsetHeight,o=w(t),s=ot.support.boxSizing&&"border-box"===ot.css(t,"boxSizing",!1,o);if(0>=i||null==i){if(i=It(t,e,o),(0>i||null==i)&&(i=t.style[e]),Vt.test(i))return i;r=s&&(ot.support.boxSizingReliable||i===t.style[e]),i=parseFloat(i)||0}return i+k(t,e,n||(s?"border":"content"),r,o)+"px"}function _(t){var e=U,n=Gt[t];return n||(n=N(t,e),"none"!==n&&n||(Bt=(Bt||ot("