leela_client 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"