borium 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2VlNWI2YzExMDA2NWVmODJmYzdiMTZmM2VkNjRhYzA5OWI3YmFkYg==
5
+ data.tar.gz: !binary |-
6
+ NjJjYWVhZmYxYmI0MGM0YzMzOTI0OWFmYTVlMGE1MWFkY2UyYWI2Mg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NDVmY2NmZmViNmYxMTk0YWEzZjA5NTUxY2Y4N2ViMjI4MTk5ZTY1N2FjMjEx
10
+ NmQ4ODUxZTRlNTE3OTA5MzYzMjkwNjE5OWU2NTYxMWQ2YjJjNGM1YmRlMDEw
11
+ YjYzZWU4M2IyOGMwNjM1ZWJlYWFiNWFkNWQwY2MzZjZhMjg1MjU=
12
+ data.tar.gz: !binary |-
13
+ YTMxYjY2NjU3ZDhlNjAxMzk2NzYzMGY1MjUzNGM5ZTAyMDZlZWY5YmRiYzA4
14
+ YzE2ZWZiZWViZDAwMjJhMmFjNjMzOWM5YzBkMTRmMzUxYjYzZmQ5MzM3ZTRl
15
+ MmUzMzA4NTZhMGQwMjNiODEwZDlhY2M3OTQzYTk2ZGQwYzQ5ZjQ=
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1 @@
1
+ borium
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p484
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem 'tokyocabinet', '1.29.1'
7
+ gem 'json', '1.8.1'
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "bundler", "1.6.2"
13
+ gem "jeweler", "2.0.1"
14
+ end
@@ -0,0 +1,59 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.6)
5
+ builder (3.2.2)
6
+ descendants_tracker (0.0.4)
7
+ thread_safe (~> 0.3, >= 0.3.1)
8
+ faraday (0.9.0)
9
+ multipart-post (>= 1.2, < 3)
10
+ git (1.2.6)
11
+ github_api (0.11.3)
12
+ addressable (~> 2.3)
13
+ descendants_tracker (~> 0.0.1)
14
+ faraday (~> 0.8, < 0.10)
15
+ hashie (>= 1.2)
16
+ multi_json (>= 1.7.5, < 2.0)
17
+ nokogiri (~> 1.6.0)
18
+ oauth2
19
+ hashie (2.1.1)
20
+ highline (1.6.21)
21
+ jeweler (2.0.1)
22
+ builder
23
+ bundler (>= 1.0)
24
+ git (>= 1.2.5)
25
+ github_api
26
+ highline (>= 1.6.15)
27
+ nokogiri (>= 1.5.10)
28
+ rake
29
+ rdoc
30
+ json (1.8.1)
31
+ jwt (0.1.13)
32
+ multi_json (>= 1.5)
33
+ mini_portile (0.6.0)
34
+ multi_json (1.10.0)
35
+ multi_xml (0.5.5)
36
+ multipart-post (2.0.0)
37
+ nokogiri (1.6.2.1)
38
+ mini_portile (= 0.6.0)
39
+ oauth2 (0.9.3)
40
+ faraday (>= 0.8, < 0.10)
41
+ jwt (~> 0.1.8)
42
+ multi_json (~> 1.3)
43
+ multi_xml (~> 0.5)
44
+ rack (~> 1.2)
45
+ rack (1.5.2)
46
+ rake (10.3.2)
47
+ rdoc (3.12.2)
48
+ json (~> 1.4)
49
+ thread_safe (0.3.3)
50
+ tokyocabinet (1.29.1)
51
+
52
+ PLATFORMS
53
+ ruby
54
+
55
+ DEPENDENCIES
56
+ bundler (= 1.6.2)
57
+ jeweler (= 2.0.1)
58
+ json (= 1.8.1)
59
+ tokyocabinet (= 1.29.1)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Freshout
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ = borium
2
+
3
+ Borium is a distributed super-queue engine, capable of storing many different kinds of queues (fifo).
4
+
5
+ Borium is tcp, and it keeps everything in queue, even if the machine crashes or is turned off it will continue right where it was at as soon as it gets restarted.
6
+
7
+ Borium Receives requests as text, and responds json, this way many different clients and workers will know how to interpret the data
8
+
9
+ Borium ensures that a requested item in queue will be given to only one client once.
10
+
11
+ Strategy is that you have two kinds of applications interacting with Borium: 1) The ones that put something in the queue. 2) The ones that get something out of the queue.
12
+
13
+ Contributors: Kazuyoshi Tlacaelel, Joaquin Benitez, Ben Beltran.
14
+
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2014 Freshout. See LICENSE.txt for
19
+ further details.
20
+
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "borium"
18
+ gem.homepage = "http://github.com/freshout-dev/borium"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Borium - Distributed background engine.}
21
+ gem.description = %Q{Borium is a distributed super-queue engine, capable of storing many different kinds of queues (fifo).}
22
+ gem.email = "kazu.dev@gmail.com"
23
+ gem.authors = ["kazuyoshi tlacaelel"]
24
+ gem.executables << 'borium'
25
+ # dependencies defined in Gemfile
26
+ end
27
+
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ desc "Code coverage detail"
38
+ task :simplecov do
39
+ ENV['COVERAGE'] = "true"
40
+ Rake::Task['test'].execute
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "borium #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'tokyocabinet'
5
+ require 'socket'
6
+ require 'digest/md5'
7
+ require 'json'
8
+ require 'logger'
9
+ require 'fileutils'
10
+
11
+ include TokyoCabinet
12
+
13
+ app = {
14
+
15
+ :databases => { },
16
+ :eot => "\004",
17
+ :must_stop => false,
18
+ :name => 'borium',
19
+ :nothing_counter => 0,
20
+
21
+ :status => {
22
+ :error => 'error', # get
23
+ :found => 'found', # get
24
+ :nothing => 'nothing', # get
25
+ :stored => 'stored', # put
26
+ :unparsable => 'unparsable' # get
27
+ },
28
+
29
+ :config => {
30
+ 'connections' => 1000,
31
+ 'host' => 'localhost',
32
+ 'log' => 'STDOUT',
33
+ 'port' => 8200,
34
+ 'storage' => '/tmp/borium/'
35
+ }
36
+
37
+ }
38
+
39
+ configuration_file = "/etc/#{app[:name]}/configuration.json"
40
+
41
+ if File.exists?(configuration_file)
42
+ config = JSON.parse(File.read(configuration_file))
43
+ else
44
+ config = app[:config]
45
+ end
46
+
47
+ if File.exists?(config['log'])
48
+ logger = Logger.new(config['log'])
49
+ else
50
+ logger = Logger.new(STDOUT)
51
+ end
52
+
53
+ terminate = Proc.new do
54
+ puts 'Bye.'
55
+ app[:must_stop] = true
56
+ logger.warn 'Going down.'
57
+ app[:databases].each do |key, hdb|
58
+ logger.warn "syncronize hdb: #{key}"
59
+ hdb.close
60
+ end
61
+ exit 0
62
+ end
63
+
64
+ trap('TERM', &terminate)
65
+ trap('INT', &terminate)
66
+ trap('QUIT', &terminate)
67
+
68
+ def generate_key
69
+ Digest::MD5.hexdigest(
70
+ Time.now.to_f.to_s + '-' + (1..100).to_a.shuffle.first.to_s
71
+ )
72
+ end
73
+
74
+ FileUtils.mkdir_p(config['storage'])
75
+ server = TCPServer.open config['host'], config['port']
76
+ server.listen(config['connections'])
77
+
78
+ logger.info 'Server started'
79
+
80
+ config.each do |key, value|
81
+ logger.info "CONFIG: #{key} => #{value}"
82
+ end
83
+
84
+ loop do
85
+ break if app[:must_stop]
86
+
87
+ client = server.accept
88
+ data = ''
89
+
90
+ while line = client.gets
91
+ data << line
92
+ break if line.include?(app[:eot])
93
+ end
94
+
95
+ chunks = data.split(':')
96
+ response = {}
97
+
98
+ # respond with error if "job_type" was not given.
99
+ if chunks.size < 3
100
+ response[:status] = app[:status][:unparsable]
101
+ begin
102
+ client.puts response.to_json
103
+ rescue => e
104
+ logger.warn 'Client closed the connection.'
105
+ end
106
+ client.close
107
+ logger.error "wrong request: #{chunks.inspect}"
108
+ next
109
+ end
110
+
111
+ request = chunks.shift
112
+ job_type = chunks.shift
113
+
114
+ unless app[:databases][job_type]
115
+ app[:databases][job_type] = HDB::new
116
+ app[:databases][job_type].open(
117
+ "#{config['storage']}/#{job_type}.job.tch",
118
+ HDB::OCREAT | HDB::OWRITER
119
+ )
120
+ end
121
+
122
+ db = app[:databases][job_type]
123
+
124
+ if (request == 'put')
125
+ db.put(generate_key, chunks.join('').gsub(app[:eot], '').gsub(/\n$/, ''))
126
+ response[:status] = app[:status][:stored]
127
+ else
128
+ db.iterinit
129
+ key = db.iternext
130
+ job = db.get(key)
131
+ if job
132
+ response[:status] = app[:status][:found]
133
+ response[:job] = job
134
+ db.out(key)
135
+ else
136
+ response[:status] = app[:status][:nothing]
137
+ end
138
+ end
139
+ result = response.to_json
140
+ begin
141
+ client.puts(result)
142
+ rescue => e
143
+ logger.warn 'Client closed the connection.'
144
+ end
145
+ client.close
146
+ if response[:status] == app[:status][:nothing]
147
+ app[:nothing_counter] += 1
148
+ if app[:nothing_counter] > 5000
149
+ logger.info "ok #{request} #{job_type} #{db.rnum.to_s} 5K => #{result}"
150
+ app[:nothing_counter] = 0
151
+ end
152
+ else
153
+ logger.info "ok #{request} #{job_type} #{db.rnum.to_s} #{result}"
154
+ end
155
+ end
156
+
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'socket'
4
+
5
+ class Borium
6
+
7
+ # @visibility private
8
+ EOT = "\004"
9
+
10
+ # @visibility private
11
+ DEFAULT_CONFIG = {
12
+ 'connections' => 1000,
13
+ 'host' => 'localhost',
14
+ 'log' => 'STDOUT',
15
+ 'port' => 8200,
16
+ 'storage' => '/tmp/borium/'
17
+ }
18
+
19
+ def self.get type
20
+ _request "get:#{type}:"
21
+ end
22
+
23
+ def self.put type, job
24
+ _request "put:#{type}:#{job}"
25
+ end
26
+
27
+ private
28
+
29
+ def self._config
30
+ @_config ||= _resolve_configuration
31
+ end
32
+
33
+ def self._resolve_configuration
34
+ configuration_file = '/etc/borium/configuration.json'
35
+ return DEFAULT_CONFIG unless File.exists?(configuration_file)
36
+ JSON.parse(File.read(configuration_file))
37
+ end
38
+
39
+ def self._request query
40
+ counter = 0
41
+ begin
42
+ counter += 1
43
+ socket = ::TCPSocket.new _config['host'], _config['port']
44
+ socket.puts query + Borium::EOT
45
+ data = ''
46
+ while line = socket.gets
47
+ break unless line
48
+ data << line
49
+ end
50
+ socket.close
51
+ return ::JSON.parse(data)
52
+ rescue => error
53
+ STDERR.puts error.message
54
+ if counter > 10
55
+ raise error
56
+ else
57
+ sleep 1
58
+ retry
59
+ end
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,34 @@
1
+ require 'simplecov'
2
+
3
+ module SimpleCov::Configuration
4
+ def clean_filters
5
+ @filters = []
6
+ end
7
+ end
8
+
9
+ SimpleCov.configure do
10
+ clean_filters
11
+ load_adapter 'test_frameworks'
12
+ end
13
+
14
+ ENV["COVERAGE"] && SimpleCov.start do
15
+ add_filter "/.rvm/"
16
+ end
17
+ require 'rubygems'
18
+ require 'bundler'
19
+ begin
20
+ Bundler.setup(:default, :development)
21
+ rescue Bundler::BundlerError => e
22
+ $stderr.puts e.message
23
+ $stderr.puts "Run `bundle install` to install missing gems"
24
+ exit e.status_code
25
+ end
26
+ require 'test/unit'
27
+ require 'shoulda'
28
+
29
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
30
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
31
+ require 'borium'
32
+
33
+ class Test::Unit::TestCase
34
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestBorium < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: borium
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - kazuyoshi tlacaelel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tokyocabinet
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.29.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.29.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 2.0.1
69
+ description: Borium is a distributed super-queue engine, capable of storing many different
70
+ kinds of queues (fifo).
71
+ email: kazu.dev@gmail.com
72
+ executables:
73
+ - borium
74
+ extensions: []
75
+ extra_rdoc_files:
76
+ - LICENSE.txt
77
+ - README.rdoc
78
+ files:
79
+ - .document
80
+ - .ruby-gemset
81
+ - .ruby-version
82
+ - Gemfile
83
+ - Gemfile.lock
84
+ - LICENSE.txt
85
+ - README.rdoc
86
+ - Rakefile
87
+ - VERSION
88
+ - bin/borium
89
+ - lib/borium.rb
90
+ - test/helper.rb
91
+ - test/test_borium.rb
92
+ homepage: http://github.com/freshout-dev/borium
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.2.2
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Borium - Distributed background engine.
116
+ test_files: []