amnesia 1.0.1 → 1.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 62ac67cfa06f569559611449d4f3a10cbd05c6683283b8fcbb6299dfcb78481e
4
+ data.tar.gz: a2cc20ea0a933faf55cb6562d3759c3b6d0a6e87661a0452382a330a7dded612
5
+ SHA512:
6
+ metadata.gz: f3fe2fe59c757c58dfb8c64a2a14f19eec9b0e6028e5140bc32fdbe22def7f09701da13e4413e5e29d078df03c5e39f4132efd4fc52aeecc84290c3a3a801764
7
+ data.tar.gz: f1e46efebdbf69f3ecc098b81ebb8f1a00cf5f213515c1024c142d2bd7c6e10a4cecd2fb7cfdac799ae845a6e23ecfdd9199ed96d7257a46b414636e0f5fb910
@@ -35,13 +35,30 @@ Available for single instances only:
35
35
 
36
36
  gem install amnesia
37
37
 
38
- ### How to run it alongside your application
38
+ ### How to run it alongside your Rack application
39
39
 
40
40
  "config.ru":
41
41
 
42
42
  require 'amnesia'
43
- use Amnesia::Application
44
- run Sinatra::Application
43
+ rack_app = Rack::Builder.app do
44
+ map "/amnesia" do
45
+ run Amnesia::Application.new
46
+ end
47
+ run YourSinatra::Application
48
+ end
49
+ run rack_app
50
+
51
+ ### How to run it alongside your Rails application
52
+
53
+ "Gemfile":
54
+
55
+ gem 'amnesia', '>=1.0.2'
56
+
57
+
58
+ "config/routes.rb":
59
+
60
+ mount Amnesia::Application.new => "/amnesia"
61
+
45
62
 
46
63
  ### Then, cruise on over to `your-host.tld/amnesia`
47
64
 
@@ -57,7 +74,7 @@ When you need to specify where your memcache hosts can be found, you can either
57
74
 
58
75
  or alternately, you can set it within your `config.ru`:
59
76
 
60
- use Amnesia::Application, :hosts => ["mc1.yourapp.com:11211", "mc2.yourapp.com:11211"]
77
+ use Amnesia::Application, hosts: ["mc1.yourapp.com:11211", "mc2.yourapp.com:11211"]
61
78
 
62
79
  ### Authentication
63
80
 
@@ -86,7 +103,7 @@ Within my slices, I punched a hole through `iptables`
86
103
 
87
104
  You won't need to do this unless you've explicitly blocked ports to your server. (When in doubt, block nearly everything)
88
105
 
89
- Let me know if you come accross any issues using Github messaging.
106
+ Let me know if you come across any issues using Github messaging.
90
107
 
91
108
  ## Something missing?
92
109
 
@@ -1,78 +1,28 @@
1
- require 'sinatra'
2
- require 'memcached'
3
- require 'gchart'
1
+ require 'sinatra/base'
2
+ require 'googlecharts'
4
3
  require 'haml'
5
-
6
- $:<< File.dirname(__FILE__)
7
-
4
+ require 'amnesia/authentication'
5
+ require 'amnesia/helpers'
8
6
  require 'amnesia/host'
9
- require 'core_ext/array'
7
+ require 'amnesia/routes'
10
8
 
11
9
  module Amnesia
12
- class << self
13
- attr_accessor :config
14
- end
15
-
16
10
  class Application < Sinatra::Base
17
- set :public, File.join(File.dirname(__FILE__), 'amnesia', 'public')
18
- set :views, File.join(File.dirname(__FILE__), 'amnesia', 'views')
11
+ include Amnesia::Authentication
12
+ include Amnesia::Helpers
13
+ include Amnesia::Routes
19
14
 
20
- def initialize(app, configuration = {})
21
- Amnesia.config = configuration
22
- # Heroku
23
- Amnesia.config[:hosts] ||= [nil] if ENV['MEMCACHE_SERVERS']
24
- # Default if nothing set
25
- Amnesia.config[:hosts] ||= ['127.0.0.1:11211']
26
- super(app)
27
- end
28
-
29
- helpers do
30
- def graph_url(data = [])
31
- GChart.pie(:data => data, :size => '115x115').to_url
32
- end
33
-
34
- def number_to_human_size(size, precision=1)
35
- size = Kernel.Float(size)
36
- case
37
- when size.to_i == 1; "1 Byte"
38
- when size < 1.kilobyte; "%d Bytes" % size
39
- when size < 1.megabyte; "%.#{precision}f KB" % (size / 1.0.kilobyte)
40
- when size < 1.gigabyte; "%.#{precision}f MB" % (size / 1.0.megabyte)
41
- when size < 1.terabyte; "%.#{precision}f GB" % (size / 1.0.gigabyte)
42
- else "%.#{precision}f TB" % (size / 1.0.terabyte)
43
- end.sub(/([0-9])\.?0+ /, '\1 ' )
44
- rescue
45
- nil
46
- end
47
-
48
- def protected!
49
- unless authorized?
50
- response['WWW-Authenticate'] = %(Basic realm="Amnesia")
51
- throw(:halt, [401, "Not authorized\n"])
52
- end
53
- end
15
+ set :public_folder, File.join(__dir__, 'amnesia', 'public')
16
+ set :views, File.join(__dir__, 'amnesia', 'views')
54
17
 
55
- def authorized?
56
- if ENV['AMNESIA_CREDS']
57
- @auth ||= Rack::Auth::Basic::Request.new(request.env)
58
- @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ENV['AMNESIA_CREDS'].split(':')
59
- else
60
- # No auth needed.
61
- true
62
- end
63
- end
64
- end
65
-
66
- get '/amnesia' do
67
- protected!
68
- @hosts = Amnesia.config[:hosts].map{|host| Amnesia::Host.new(host)}
69
- haml :index
18
+ def initialize(app = nil, options = {})
19
+ @hosts = build_hosts options[:hosts] || ENV['MEMCACHE_SERVERS'] || '127.0.0.1:11211'
20
+ super app
70
21
  end
71
22
 
72
- get '/amnesia/:host' do
73
- protected!
74
- @host = Amnesia::Host.new(params[:host])
75
- haml :host
23
+ def build_hosts addresses
24
+ addresses = addresses.split "," if addresses.is_a? String
25
+ Array(addresses).flatten.map { |address| Amnesia::Host.new address }
76
26
  end
77
27
  end
78
28
  end
@@ -0,0 +1,12 @@
1
+ module Amnesia
2
+ module Authentication
3
+ def self.included app
4
+ app.class_eval do
5
+ use Rack::Auth::Basic, "Amnesia" do |username, password|
6
+ user, pass = ENV['AMNESIA_CREDS'].split(':')
7
+ username == user and password == pass
8
+ end if ENV['AMNESIA_CREDS']
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ module Amnesia
2
+ module Helpers
3
+ def self.included app
4
+ app.helpers do
5
+ include HelperMethods
6
+ end
7
+ end
8
+
9
+ module HelperMethods
10
+ SIZE_UNITS = %w[ Bytes KB MB GB TB PB EB ]
11
+
12
+ def graph_url(*data)
13
+ Gchart.pie(data: data, size: '115x115', bg: 'ffffff00')
14
+ end
15
+
16
+ # https://github.com/rails/rails/blob/fbe335cfe09bf0949edfdf0c4b251f4d081bd5d7/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
17
+ def number_to_human_size(number, precision=1)
18
+ number, base = Float(number), 1024
19
+
20
+ if number.to_i < base
21
+ "%d %s" % [ number.to_i, SIZE_UNITS.first ]
22
+ else
23
+ max = SIZE_UNITS.size - 1
24
+ exp = (Math.log(number) / Math.log(base)).to_i
25
+ exp = max if exp > max # avoid overflow for the highest unit
26
+ result = number / (base**exp)
27
+ "%.#{precision}f %s" % [ result, SIZE_UNITS[exp] ]
28
+ end
29
+ end
30
+
31
+ def alive_hosts
32
+ @alive_hosts ||= @hosts.select(&:alive?)
33
+ end
34
+
35
+ %w[ bytes limit_maxbytes get_hits get_misses cmd_get cmd_set ].each do |stat|
36
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
37
+ def #{stat}_sum
38
+ alive_hosts.map(&:#{stat}).sum
39
+ end
40
+ RUBY
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,34 +1,58 @@
1
+ require 'dalli'
2
+
1
3
  module Amnesia
2
4
  class Host
5
+ FLOAT_STATS = %w[ rusage_user rusage_system ]
6
+ STRING_STATS = %w[ version libevent ]
7
+
3
8
  def initialize(address)
4
9
  @address = address
5
10
  end
6
-
7
- def alive?
8
- return true if connection.stats
9
- rescue Memcached::Error
11
+
12
+ def alive?
13
+ return true if connection.stats[@address]
14
+ rescue Dalli::DalliError
10
15
  return false
11
16
  end
12
-
17
+
13
18
  def method_missing(method, *args)
14
- stats[method.to_s.to_sym].sum if stats.has_key? method.to_s.to_sym
19
+ if stats.has_key? method.to_s
20
+ value = stats[method.to_s]
21
+ if FLOAT_STATS.include? method
22
+ Float(value)
23
+ elsif STRING_STATS.include? method
24
+ value
25
+ else
26
+ Integer(value)
27
+ end
28
+ else
29
+ super
30
+ end
15
31
  end
16
-
32
+
17
33
  def stats
18
- connection.stats[connection.stats.keys.first]
19
- connection.stats
20
- rescue Memcached::Error
21
- return {}
34
+ stats_val = connection.stats
35
+ stats_val.values.first || {}
22
36
  end
23
37
 
24
38
  def address
25
39
  @address || @connection.servers.join(', ')
26
40
  end
27
-
41
+
28
42
  private
29
-
43
+
30
44
  def connection
31
- @connection ||= @address ? Memcached.new(@address) : Memcached.new
45
+ @connection ||= connect(@address)
32
46
  end
47
+
48
+ def connect(address = nil)
49
+ if defined?(EM) && EM.respond_to?(:reactor_running?) && EM::reactor_running?
50
+ opts = {async: true}
51
+ else
52
+ opts = {}
53
+ end
54
+ Dalli::Client.new(address, opts)
55
+ end
56
+
33
57
  end
34
58
  end
@@ -1,38 +1,87 @@
1
- /* HTML5 */
2
- header, footer, article, section, aside, nav, menu, figure { display: block; }
1
+ body, h1, h2, h3, h4, h5, h6, p, a, ul, ol, dl, dt, dd, table, caption, th, td,
2
+ fieldset, legend, blockquote {
3
+ font-weight: normal;
4
+ margin: 0;
5
+ padding: 0;
6
+ color: inherit;
7
+ list-style-type: none;
8
+ }
9
+ a img, form, legend {border: 0; }
3
10
 
4
- /* Resets */
5
- body, h1, h2, h3, h4, h5, h6, p, a, ul, ol, dl, dt, dd, table, caption, th, td, fieldset, legend, blockquote { font-weight: normal; margin: 0; padding: 0; color: inherit; list-style-type: none; }
6
- a img, form, legend { border: 0; }
11
+ html { color: #454545;}
7
12
 
8
- /* Layout */
9
- body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 0 auto; width: 450px; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }
13
+ body {
14
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
15
+ margin: 0 auto;
16
+ padding: 0 1em;
17
+ max-width: 450px;
18
+ text-rendering: optimizeLegibility;
19
+ -webkit-font-smoothing: antialiased;
20
+ }
10
21
 
11
- h1, h2, h3 { color: #1f1f1f; }
12
22
  img { display: block; }
13
- a { color: inherit; }
23
+ a:hover { color: #000; }
14
24
 
15
25
  header { margin: 1em 0; }
16
- header h1 { font-size: 3.5em; }
17
- header h1 a { color: #1f1f1f; text-decoration: none; }
18
- header h1 a:hover:after { content: "—Huh?";}
19
- header p { font-size: 0.8em; color: #454545; }
26
+ .brand { font-size: 3.5em; }
27
+ .brand a { display: block; text-decoration: none; }
28
+ .brand a:hover:after { content: "—Huh?";}
20
29
 
21
- section#main h2 { font-size: 1em; float: right; }
22
- section#main p.sub { color: #666; font-size: 0.9em; font-style: italic; }
30
+ .host {
31
+ font-size: 1em;
32
+ color: #fff;
33
+ }
34
+ .host-address {
35
+ font-weight: bold;
36
+ color: #ff9900;
37
+ border-radius: 2px;
38
+ font-size: 0.9em;
39
+ }
40
+ .host-details {
41
+ color: #000;
42
+ padding: 2px 4px;
43
+ }
23
44
 
24
- section#main .stats { clear: left; padding: 1.75em 0; }
25
- section#main :last-child { border: none; }
26
- section#main .graph img { float: left; margin-top: -1.5em; margin-left: -1em; }
27
- section#main .stats h3 { font-size: 1.1em; margin-left: 110px; line-height: 1.5em; }
28
- section#main .stats p { line-height: 1.4em; font-size: 0.75em; color: #454545; margin-left: 110px; }
45
+ .stats {
46
+ display: flex;
47
+ align-items: center;
48
+ margin: 2em 0;
49
+ }
50
+ .stats-graph img { margin-left: -10px; }
51
+ .stats-text {
52
+ flex: 1 1;
53
+ margin-left: 1em;
54
+ }
29
55
 
30
- section#main .stats h3 span.graph-indicator { color: #ff9900; }
56
+ .graph-indicator { color: #ff9900; }
31
57
 
32
- nav#hosts { clear: left; margin: 2em 0; }
33
- nav#hosts li { margin: 0.5em 0; }
34
- nav#hosts li.inactive { color: #999; }
58
+ .alive-host,
59
+ .dead-host {
60
+ margin: 0.5em 0;
61
+ }
62
+ .dead-host { color: #999; }
35
63
 
36
- footer { margin-top: 2em; border-top: 0.1em dotted #eee; width: 50%; margin: 2em auto; padding: 0.5em 0; }
37
- footer p { font-size: 0.6em; color: #ccc; text-align: center; }
38
- footer p a:hover { color: #999; }
64
+ footer {
65
+ margin-top: 2em;
66
+ border-top: 0.1em solid #ccc;
67
+ margin: 2em auto;
68
+ padding: 0.5em 0;
69
+ font-size: 0.8em;
70
+ color: #ccc;
71
+ text-align: center;
72
+ }
73
+ footer a:hover { color: #999; }
74
+
75
+ @media (prefers-color-scheme: dark) {
76
+ html {
77
+ background: black;
78
+ color: white;
79
+ color: #ccc;
80
+ }
81
+ a:hover { color: #fff; }
82
+ footer { border-color: #454545; color: #454545; }
83
+ .host-details {
84
+ color: #fff;
85
+ }
86
+
87
+ }
@@ -0,0 +1,20 @@
1
+ module Amnesia
2
+ module Routes
3
+ def self.included app
4
+ app.class_eval do
5
+ get '/' do
6
+ haml :index
7
+ end
8
+
9
+ get '/:address' do
10
+ @host = find_host params[:address]
11
+ @host ? haml(:host) : halt(404)
12
+ end
13
+
14
+ def find_host address
15
+ @hosts.find { |h| h.address == address }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,24 +1,32 @@
1
- %h2= @host.address
2
- %p.sub #{@host.curr_items} item/s in cache, with #{@host.curr_connections} active connections
1
+ %h2.host
2
+ %span.host-address
3
+ = @host.address
4
+ %small.host-details
5
+ = "#{@host.curr_items} item/s in cache, with #{@host.curr_connections} active connections"
3
6
 
4
- %section.stats.graph
5
- %img{:src => graph_url([@host.bytes, @host.limit_maxbytes]) }
6
- %h3
7
- %span.graph-indicator Used Memory (#{number_to_human_size(@host.bytes)})
8
- \/ Free Memory (#{number_to_human_size(@host.limit_maxbytes)})
9
- %p The cumulative amount of free memory and total memory across all active hosts.
7
+ %article.stats
8
+ %section.stats-graph
9
+ %img{src: graph_url(@host.bytes, @host.limit_maxbytes) }
10
+ %section.stats-text
11
+ %h3
12
+ %span.graph-indicator Used Memory (#{number_to_human_size(@host.bytes)})
13
+ \/ Free Memory (#{number_to_human_size(@host.limit_maxbytes)})
14
+ %p The cumulative amount of free memory and total memory across all active hosts.
10
15
 
16
+ %article.stats
17
+ %section.stats-graph
18
+ %img{src: graph_url(@host.get_hits, @host.get_misses) }
19
+ %section.stats-text
20
+ %h3
21
+ %span.graph-indicator Hit (#{@host.get_hits})
22
+ \/ Miss (#{@host.get_misses})
23
+ %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
11
24
 
12
- %section.stats.graph
13
- %img{:src => graph_url([@host.get_hits, @host.get_misses]) }
14
- %h3
15
- %span.graph-indicator Hit (#{@host.get_hits})
16
- \/ Miss (#{@host.get_misses})
17
- %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
18
-
19
- %section.stats.graph
20
- %img{:src => graph_url([@host.cmd_get, @host.cmd_set]) }
21
- %h3
22
- %span.graph-indicator Read (#{@host.cmd_get})
23
- \/ Write (#{@host.cmd_set})
24
- %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
25
+ %section.stats
26
+ %section.stats-graph
27
+ %img{src: graph_url(@host.cmd_get, @host.cmd_set) }
28
+ %section.stats-text
29
+ %h3
30
+ %span.graph-indicator Read (#{@host.cmd_get})
31
+ \/ Write (#{@host.cmd_set})
32
+ %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
@@ -1,34 +1,39 @@
1
- - if @hosts.any?{|host| host.alive? }
2
- %section#overall
3
- %section.stats.graph
4
- %img{:src => graph_url([@hosts.collect{|h| h.get_hits if h.alive? }.compact.sum, @hosts.collect{|h| h.get_misses if h.alive? }.compact.sum])}
1
+ - if alive_hosts.any?
2
+ %article.stats
3
+ %section.stats-graph
4
+ %img{src: graph_url(bytes_sum, limit_maxbytes_sum)}
5
+ %section.stats-text
5
6
  %h3
6
- %span.graph-indicator Hit
7
- \/ Miss
7
+ %span.graph-indicator Used Memory (#{number_to_human_size(bytes_sum)})
8
+ \/ Free Memory (#{number_to_human_size(limit_maxbytes_sum)})
9
+ %p The cumulative amount of free memory and total memory across all active hosts.
10
+
11
+ %article.stats
12
+ %section.stats-graph
13
+ %img{src: graph_url(get_hits_sum, get_misses_sum)}
14
+ %section.stats-text
15
+ %h3
16
+ %span.graph-indicator Hit (#{get_hits_sum})
17
+ \/ Miss (#{get_misses_sum})
8
18
  %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
9
- %section.stats.graph
10
- %img{:src => graph_url([@hosts.collect{|h| h.cmd_get if h.alive? }.compact.sum, @hosts.collect{|h| h.cmd_set if h.alive? }.compact.sum])}
19
+
20
+ %article.stats
21
+ %section.stats-graph
22
+ %img{src: graph_url(cmd_get_sum, cmd_set_sum)}
23
+ %section.stats-text
11
24
  %h3
12
- %span.graph-indicator Read
13
- \/ Write
25
+ %span.graph-indicator Read (#{cmd_get_sum})
26
+ \/ Write (#{cmd_set_sum})
14
27
  %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
15
-
16
- %section.stats.graph
17
- %img{:src => graph_url([@hosts.collect{|h| h.bytes if h.alive? }.compact.sum, @hosts.collect{|h| h.limit_maxbytes if h.alive? }.compact.sum])}
18
- %h3
19
- %span.graph-indicator Used Memory
20
- \/ Free Memory
21
- %p The cumulative amount of free memory and total memory across all active hosts.
22
28
 
23
- %nav#hosts
24
- %p.sub Active Hosts
29
+ %nav
30
+ %p.sub Known Hosts
25
31
  %ul
26
32
  - for host in @hosts
27
33
  - if host.alive?
28
- %li
29
- %a{:href => "/amnesia/" + host.address }= host.address
34
+ %li.alive-host
35
+ %a{href: url("/#{host.address}") }= host.address
30
36
  - else
31
- %li.inactive
37
+ %li.dead-host
32
38
  = host.address
33
39
  (Inactive)
34
-
@@ -1,19 +1,19 @@
1
1
  !!!
2
2
  %html
3
3
  %head
4
- %meta{:charset => "utf-8"}
4
+ %meta{charset: "utf-8"}
5
5
  %title Amnesia
6
- %link{:rel => "stylesheet", :href => "/css/application.css"}
6
+ %link{rel: "stylesheet", href: url("/css/application.css")}
7
7
  %body
8
8
  %header
9
- %h1
10
- %a{:href => '/amnesia'} Amnesia
9
+ %h1.brand
10
+ %a{href: url('/')} Amnesia
11
11
  %p Statistics for Memcached. Wait—What?
12
- %section#main
12
+ %main
13
13
  = yield
14
14
  %footer
15
- %p
15
+ %p
16
16
  Another
17
- %a{:href => "http://germanforblack.com"} Ben Schwarz
18
- joint. Get the
19
- %a{:href => "http://github.com/benschwarz/amnesia"} Source.
17
+ %a{href: "http://germanforblack.com"} Ben Schwarz
18
+ joint. Get the
19
+ %a{href: "http://github.com/benschwarz/amnesia"} Source.
metadata CHANGED
@@ -1,132 +1,138 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: amnesia
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 1
9
- version: 1.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Ben Schwarz
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2010-10-02 00:00:00 +10:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2020-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: sinatra
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
26
17
  - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 1
30
- - 0
31
- version: "1.0"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
32
20
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: memcached-northscale
36
21
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dalli
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
40
31
  - - ">="
41
- - !ruby/object:Gem::Version
42
- segments:
43
- - 0
44
- - 19
45
- - 5
46
- - 4
47
- version: 0.19.5.4
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
48
34
  type: :runtime
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: gchart
52
35
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
56
- - - "="
57
- - !ruby/object:Gem::Version
58
- segments:
59
- - 1
60
- - 0
61
- - 0
62
- version: 1.0.0
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: googlecharts
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.8
63
48
  type: :runtime
64
- version_requirements: *id003
65
- - !ruby/object:Gem::Dependency
66
- name: haml
67
49
  prerelease: false
68
- requirement: &id004 !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.8
55
+ - !ruby/object:Gem::Dependency
56
+ name: haml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
71
59
  - - ">="
72
- - !ruby/object:Gem::Version
73
- segments:
74
- - 3
75
- - 0
76
- - 0
77
- version: 3.0.0
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
78
62
  type: :runtime
79
- version_requirements: *id004
80
- description: With Amnesia you'll know exactly whats happening with memory when it comes to memcached.
81
- email:
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-test
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: With Amnesia you'll know exactly whats happening with memory when it
98
+ comes to memcached.
99
+ email:
82
100
  - ben.schwarz@gmail.com
83
101
  executables: []
84
-
85
102
  extensions: []
86
-
87
103
  extra_rdoc_files: []
88
-
89
- files:
104
+ files:
105
+ - LICENCE
106
+ - README.markdown
107
+ - lib/amnesia.rb
108
+ - lib/amnesia/authentication.rb
109
+ - lib/amnesia/helpers.rb
90
110
  - lib/amnesia/host.rb
91
111
  - lib/amnesia/public/css/application.css
112
+ - lib/amnesia/routes.rb
92
113
  - lib/amnesia/views/host.haml
93
114
  - lib/amnesia/views/index.haml
94
115
  - lib/amnesia/views/layout.haml
95
- - lib/amnesia.rb
96
- - lib/core_ext/array.rb
97
- - LICENCE
98
- - README.markdown
99
- has_rdoc: true
100
116
  homepage: http://github.com/benschwarz/amnesia
101
117
  licenses: []
102
-
118
+ metadata: {}
103
119
  post_install_message:
104
120
  rdoc_options: []
105
-
106
- require_paths:
121
+ require_paths:
107
122
  - lib
108
- required_ruby_version: !ruby/object:Gem::Requirement
109
- none: false
110
- requirements:
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
111
125
  - - ">="
112
- - !ruby/object:Gem::Version
113
- segments:
114
- - 0
115
- version: "0"
116
- required_rubygems_version: !ruby/object:Gem::Requirement
117
- none: false
118
- requirements:
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
119
130
  - - ">="
120
- - !ruby/object:Gem::Version
121
- segments:
122
- - 0
123
- version: "0"
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
124
133
  requirements: []
125
-
126
- rubyforge_project:
127
- rubygems_version: 1.3.7
134
+ rubygems_version: 3.0.3
128
135
  signing_key:
129
- specification_version: 3
136
+ specification_version: 4
130
137
  summary: Amnesia is what you get when you lose your memory
131
138
  test_files: []
132
-
@@ -1,5 +0,0 @@
1
- class Array
2
- def sum
3
- inject( nil ) { |sum,x| sum ? sum+x : x }
4
- end
5
- end