leela_client 0.0.2 → 0.0.3

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,34 @@
1
+ # -*- encoding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "resolv"
18
+
19
+ DEFAULT_PORT = 6968
20
+
21
+ module LeelaClient
22
+ module Api
23
+ extend self
24
+
25
+ def transport(servers)
26
+ servers = servers.map do |addr|
27
+ host, port = addr.split(":", 2)
28
+ [Resolv.getaddress(host), (port || 6968).to_i]
29
+ end
30
+
31
+ UDPTransport.new MD5Ring.from_list(servers)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module LeelaClient
18
+ module LoadBalancer
19
+ extend self
20
+
21
+ def group(ring, metrics)
22
+ group = Hash[ ring.values.map {|x| [x, []]} ]
23
+ metrics.each do |m|
24
+ node = ring.select(m.key)
25
+ group[node] << m
26
+ end
27
+
28
+ group
29
+ end
30
+
31
+ def group_limit(ring, metrics, maxsize)
32
+ g1 = {}
33
+ c = 0
34
+
35
+ group(ring, metrics).each do |k, ms|
36
+ g1[k] = [[]]
37
+ ms.each do |m|
38
+ c += m.size
39
+ g1[k][-1] << m
40
+ if (c >= maxsize)
41
+ c = 0
42
+ g1[k] << []
43
+ end
44
+ end
45
+ end
46
+
47
+ g1
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,90 @@
1
+ # -*- encoding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module LeelaClient
18
+ module Metric
19
+ attr_reader :type
20
+ attr_accessor :key
21
+ attr_accessor :value
22
+ attr_accessor :timestamp
23
+
24
+ def serialize
25
+ size = @key.size
26
+ now = @timestamp.to_f.to_s
27
+ if (@value.integer?)
28
+ value = @value.to_f.to_s
29
+ elsif (@value.nan?)
30
+ value = "nan"
31
+ elsif (@value.infinite? == 1)
32
+ value = "inf"
33
+ elsif (@value.infinite? == -1)
34
+ value = "-inf"
35
+ else
36
+ value = @value.to_s
37
+ end
38
+
39
+ "#{@type} #{size}|#{@key} #{value} #{now};"
40
+ end
41
+
42
+ def size
43
+ self.serialize.size
44
+ end
45
+ end
46
+
47
+ class Gauge
48
+ include Metric
49
+
50
+ def initialize(key, value)
51
+ @type = "gauge"
52
+ @key = key
53
+ @value = value
54
+ @timestamp = Time.now
55
+ end
56
+ end
57
+
58
+ class Counter
59
+ include Metric
60
+
61
+ def initialize(key, value)
62
+ @type = "counter"
63
+ @key = key
64
+ @value = value
65
+ @timestamp = Time.now
66
+ end
67
+ end
68
+
69
+ class Derive
70
+ include Metric
71
+
72
+ def initialize(key, value)
73
+ @type = "derive"
74
+ @key = key
75
+ @value = value
76
+ @timestamp = Time.now
77
+ end
78
+ end
79
+
80
+ class Absolute
81
+ include Metric
82
+
83
+ def initialize(key, value)
84
+ @type = "absolute"
85
+ @key = key
86
+ @value = value
87
+ @timestamp = Time.now
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,85 @@
1
+ # -*- encoding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "set"
18
+ require "digest/md5"
19
+
20
+ module LeelaClient
21
+ class Ring
22
+ def token(key)
23
+ raise(RuntimeError.new "abstract method")
24
+ end
25
+
26
+ def add_token!(token, value)
27
+ raise(RuntimeError.new "abstract method")
28
+ end
29
+
30
+ def rm_token!(token)
31
+ raise(RuntimeError.new "abstract method")
32
+ end
33
+
34
+ def select(token)
35
+ raise(RuntimeError.new "abstract method")
36
+ end
37
+
38
+ def values
39
+ raise(RuntimeError.new "abstract method")
40
+ end
41
+ end
42
+
43
+ class MD5Ring < Ring
44
+ def self.from_list(values)
45
+ ring = MD5Ring.new
46
+ step = 2**128 / values.size
47
+ token = 0
48
+ Set.new(values).sort.each do |v|
49
+ ring.add_token!(token, v)
50
+ token += step
51
+ end
52
+
53
+ ring
54
+ end
55
+
56
+ def initialize
57
+ @ring = {}
58
+ end
59
+
60
+ def token(key)
61
+ Digest::MD5.hexdigest(key).to_i(16)
62
+ end
63
+
64
+ def add_token!(token, value)
65
+ @ring[token] = value
66
+ end
67
+
68
+ def rm_token!(token)
69
+ @ring.delete(token)
70
+ end
71
+
72
+ def values
73
+ @ring.values
74
+ end
75
+
76
+ def select(value)
77
+ self.select_(self.token(value))
78
+ end
79
+
80
+ def select_(token)
81
+ k = @ring.keys.sort.select {|x| x < token}.last
82
+ @ring[k]
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module LeelaClient
18
+ class UDPTransport
19
+ MAXPAYLOAD = 1472
20
+
21
+ def initialize(ring)
22
+ @ring = ring
23
+ @sock = UDPSocket.new
24
+ end
25
+
26
+ def serialize_list(metrics)
27
+ metrics.map(&:serialize).join("")
28
+ end
29
+
30
+ def send(metrics)
31
+ LeelaClient::LoadBalancer.group_limit(@ring, metrics, MAXPAYLOAD).each do |addr, mms|
32
+ mms.each do |ms|
33
+ sent = @sock.send(serialize_list(ms), 0, addr[0], addr[1])
34
+ raise if (sent > MAXPAYLOAD)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module LeelaClient
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/leela_client.gemspec CHANGED
@@ -1,19 +1,16 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/leela_client/version', __FILE__)
2
+ require File.expand_path('../leela_client/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["PotHix", "ncode"]
6
- gem.email = ["pothix@pothix.com", "juliano.martinez@gmail.com"]
5
+ gem.authors = ["PotHix", "dgvncsz0f"]
6
+ gem.email = ["pothix@pothix.com", "dgvncsz0f@bitforest.com"]
7
7
  gem.description = %q{A client for leela chart server}
8
- gem.summary = gem.description
9
- gem.homepage = "https://github.com/ncode/leela"
8
+ gem.summary = gem.description
9
+ gem.homepage = "https://github.com/locaweb/leela-client"
10
10
 
11
11
  gem.files = Dir["./**/*"].reject {|file| file =~ /\.git|pkg/}
12
- gem.require_paths = ["lib"]
12
+ gem.require_paths = ["leela_client"]
13
13
 
14
14
  gem.name = "leela_client"
15
15
  gem.version = LeelaClient::VERSION
16
-
17
- gem.add_dependency "bzip2-ruby"
18
- gem.add_development_dependency "rspec"
19
16
  end
data/leela_client.rb ADDED
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8; -*-
2
+ #
3
+ # All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "leela_client/api"
18
+ require "leela_client/lb"
19
+ require "leela_client/metrics"
20
+ require "leela_client/ring"
21
+ require "leela_client/transport"
22
+ require "leela_client/version"
metadata CHANGED
@@ -1,61 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leela_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - PotHix
9
- - ncode
9
+ - dgvncsz0f
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-28 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: bzip2-ruby
17
- requirement: &12335200 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: '0'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: *12335200
26
- - !ruby/object:Gem::Dependency
27
- name: rspec
28
- requirement: &12334600 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: *12334600
13
+ date: 2013-04-17 00:00:00.000000000 Z
14
+ dependencies: []
37
15
  description: A client for leela chart server
38
16
  email:
39
17
  - pothix@pothix.com
40
- - juliano.martinez@gmail.com
18
+ - dgvncsz0f@bitforest.com
41
19
  executables: []
42
20
  extensions: []
43
21
  extra_rdoc_files: []
44
22
  files:
45
- - ./Gemfile.lock
46
- - ./leela_client.gemspec
47
- - ./spec/spec_helper.rb
48
- - ./spec/leela_client_spec.rb
49
- - ./Gemfile
23
+ - ./leela_client/version.rb
24
+ - ./leela_client/transport.rb
25
+ - ./leela_client/api.rb
26
+ - ./leela_client/ring.rb
27
+ - ./leela_client/lb.rb
28
+ - ./leela_client/metrics.rb
50
29
  - ./Rakefile
51
- - ./lib/leela_client/version.rb
52
- - ./lib/leela_client.rb
53
- homepage: https://github.com/ncode/leela
30
+ - ./leela_client.gemspec
31
+ - ./leela_client.rb
32
+ homepage: https://github.com/locaweb/leela-client
54
33
  licenses: []
55
34
  post_install_message:
56
35
  rdoc_options: []
57
36
  require_paths:
58
- - lib
37
+ - leela_client
59
38
  required_ruby_version: !ruby/object:Gem::Requirement
60
39
  none: false
61
40
  requirements:
@@ -70,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
49
  version: '0'
71
50
  requirements: []
72
51
  rubyforge_project:
73
- rubygems_version: 1.8.16
52
+ rubygems_version: 1.8.23
74
53
  signing_key:
75
54
  specification_version: 3
76
55
  summary: A client for leela chart server
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in leela_client.gemspec
4
- gemspec
data/Gemfile.lock DELETED
@@ -1,26 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- leela_client (0.0.1)
5
- bzip2-ruby
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- bzip2-ruby (0.2.7)
11
- diff-lcs (1.1.3)
12
- rspec (2.8.0)
13
- rspec-core (~> 2.8.0)
14
- rspec-expectations (~> 2.8.0)
15
- rspec-mocks (~> 2.8.0)
16
- rspec-core (2.8.0)
17
- rspec-expectations (2.8.0)
18
- diff-lcs (~> 1.1.2)
19
- rspec-mocks (2.8.0)
20
-
21
- PLATFORMS
22
- ruby
23
-
24
- DEPENDENCIES
25
- leela_client!
26
- rspec
data/lib/leela_client.rb DELETED
@@ -1,27 +0,0 @@
1
- require "leela_client/version"
2
- require "socket"
3
- require "bzip2"
4
-
5
- module LeelaClient
6
- class Client
7
- attr_reader :data
8
-
9
- def initialize(service, server="127.0.0.1", port=6968)
10
- @server, @port = server, port
11
- @service = service
12
- @data = []
13
- end
14
-
15
- def add(name, value)
16
- @data << "#{name}|#{value}"
17
- end
18
-
19
- def publish
20
- sock = UDPSocket.new
21
- sock.connect(@server, @port)
22
-
23
- message = "#{Socket.gethostname}|#{@service}||" + @data.join("||")
24
- sock.send(Bzip2.compress(message, 9), 0)
25
- end
26
- end
27
- end
@@ -1,29 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe LeelaClient do
4
- it "shold add the correct data in normal order" do
5
- leela = LeelaClient::Client.new "service"
6
-
7
- leela.data.should be_empty
8
- leela.add("attr", 10)
9
- leela.data.should have(1).item
10
-
11
- leela.add("attr", 20)
12
- leela.data.should have(2).items
13
- leela.data.last.should eql("attr|20")
14
- end
15
-
16
- it "should send the complete information to the socket" do
17
- host = "machine"
18
- Socket.stub(:gethostname).and_return(host)
19
-
20
- sock = UDPSocket.new
21
- sock.bind("127.0.0.1",6968)
22
-
23
- leela = LeelaClient::Client.new("service", "127.0.0.1", 6968)
24
- leela.add("param", 50)
25
- leela.publish
26
-
27
- sock.recvfrom(100)[0].should eql(Bzip2.compress("machine|service||param|50",9))
28
- end
29
- end
data/spec/spec_helper.rb DELETED
@@ -1 +0,0 @@
1
- require "leela_client"