worker_scoreboard 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9911d8e7cd1e186fa678c4c0ca8b5235d91fa53a
4
+ data.tar.gz: ac956ee07a9dd8bfb8e217fa291245c15506be42
5
+ SHA512:
6
+ metadata.gz: 405828e79c6c1fcf769dafff8f273867f21d7e67d19a938c0b248a14c4334f92e39786c7aad84c8223dd218bbfbb7a803ffb074e6d3fc8442f9854b45e972359
7
+ data.tar.gz: d91460ba6dbd6bf854d9f7204f161074354ec96fa477ff6691b4da949c02ab5f28795f08c5787861f3167c73650098825830b87f5217f8c29bb7ecf8f6e64cbc
data/.consolerc ADDED
@@ -0,0 +1,3 @@
1
+ # This file is automatically loaded when `bundle console` is run. You can add
2
+ # fixtures and/or initialization code here to make experimenting with your gem
3
+ # easier.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.2
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in worker_scoreboard.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry'
8
+ end
9
+ group :test do
10
+ end
11
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright 2015 SpringMT
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # WorkerScoreboard [![Build Status](https://travis-ci.org/SpringMT/worker_scoreboard.svg)](https://travis-ci.org/SpringMT/worker_scoreboard)
2
+
3
+ This is a Ruby version of [kazuho/p5-Parallel-Scoreboard](https://github.com/kazuho/p5-Parallel-Scoreboard).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'worker_scoreboard'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install worker_scoreboard
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/worker_scoreboard/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -0,0 +1,3 @@
1
+ class WorkerScoreboard
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,117 @@
1
+ require "worker_scoreboard/version"
2
+ require 'digest/md5'
3
+
4
+ class WorkerScoreboard
5
+ def initialize(base_dir)
6
+ fail 'mandatory parameter:base_dir is missing' if base_dir.nil?
7
+ @base_dir = base_dir
8
+
9
+ @fh = nil
10
+ @id_for_fh = nil
11
+
12
+ # [path, filehandler]
13
+ @data = [build_filename, @fh]
14
+ @clean_proc = Remover.new(@data)
15
+ ObjectSpace.define_finalizer(self, @clean_proc)
16
+
17
+ unless Dir.exist? @base_dir
18
+ Dir.mkdir @base_dir or fail "failed to create directory:#{@base_dir}:#{$!}"
19
+ end
20
+ begin
21
+ File.unlink build_filename
22
+ rescue
23
+ end
24
+ end
25
+
26
+ def update(status)
27
+ if !@fh.nil? && @id_for_fh != worker_id
28
+ @fh.close
29
+ @fh = nil
30
+ end
31
+
32
+ if @fh.nil?
33
+ filename = build_filename
34
+ tmp_filename = "#{filename}.tmp"
35
+ f = File.open(tmp_filename, 'wb')
36
+ f.flush
37
+ f.flock File::LOCK_EX or raise "failed to flock LOCK_EX file:#{@fn}.tmp:#{$!}"
38
+ File.rename(tmp_filename, filename) or raise "failed to rename file:#{@fn.tmp} to #{@fn}:#{$!}"
39
+ @fh = f
40
+ @id_for_fh = worker_id
41
+ end
42
+ @fh.seek 0 or raise "seek failed:#{$!}";
43
+ @fh.write("#{Digest::MD5.digest(status)}#{[status.length].pack("N*")}#{status}")
44
+ @fh.flush
45
+ end
46
+
47
+ def read_all
48
+ ret = {}
49
+ for_all do |id, fh|
50
+ 10.times do
51
+ fh.seek 0 or raise "seek failed:#{$!}"
52
+ data = fh.read
53
+ break if data.length < 16 + 4
54
+ md5 = data[0, 16]
55
+ size = data[16, 4].unpack("N*")
56
+ status = data[20, size[0]]
57
+ next if Digest::MD5.digest(status) != md5
58
+ ret[id] = status
59
+ break
60
+ end
61
+ #warn "failed to read status of id:#{id}, skipping"
62
+ end
63
+ ret
64
+ end
65
+
66
+ def cleanup
67
+ for_all
68
+ end
69
+
70
+ private
71
+
72
+ def worker_id
73
+ Process.pid
74
+ end
75
+
76
+ def for_all
77
+ files = Dir.glob("#{@base_dir}/status_*")
78
+ files.each do |file|
79
+ file =~ /\/status_(.*)$/ or next
80
+ id = $1
81
+ fh = File.open(file, 'r+b') or next
82
+ if id != worker_id && fh.flock(File::LOCK_EX|File::LOCK_NB)
83
+ fh.close
84
+ File.unlink file or not $! === Errno::ENOENT and warn "failed to remove an obsolete scoreboard file:#{file}:#{$!}"
85
+ next
86
+ end
87
+ yield id, fh
88
+ fh.close
89
+ end
90
+ end
91
+
92
+ def build_filename
93
+ "#{@base_dir}/status_#{worker_id}"
94
+ end
95
+
96
+ class Remover
97
+ def initialize(data)
98
+ @pid = $$
99
+ @data = data
100
+ end
101
+
102
+ def call(*args)
103
+ return if @pid != $$
104
+ path, tmpfile = @data
105
+ STDERR.print "removing ", path, "..." if $DEBUG
106
+ tmpfile.close if tmpfile
107
+ if path
108
+ begin
109
+ File.unlink(path)
110
+ rescue Errno::ENOENT
111
+ end
112
+ end
113
+ STDERR.print "done\n" if $DEBUG
114
+ end
115
+ end
116
+
117
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'worker_scoreboard'
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ describe WorkerScoreboard do
5
+ context do
6
+ let(:base_dir) { Dir.tmpdir }
7
+ subject { WorkerScoreboard.new(base_dir) }
8
+ it do
9
+ subject.update('me manager')
10
+ expect(subject.read_all.values.first).to eq 'me manager'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'worker_scoreboard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "worker_scoreboard"
8
+ spec.version = WorkerScoreboard::VERSION
9
+ spec.authors = ["SpringMT"]
10
+ spec.email = ["today.is.sky.blue.sky@gmail.com"]
11
+
12
+ #spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
13
+ spec.required_rubygems_version = ">= 2.0"
14
+
15
+ spec.summary = %q{a scoreboard for monitoring status of many workers}
16
+ spec.description = %q{a scoreboard for monitoring status of many workers}
17
+ spec.homepage = "https://github.com/SpringMT/worker_scoreboard"
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.7"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec"
28
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: worker_scoreboard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - SpringMT
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: a scoreboard for monitoring status of many workers
56
+ email:
57
+ - today.is.sky.blue.sky@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".consolerc"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - lib/worker_scoreboard.rb
71
+ - lib/worker_scoreboard/version.rb
72
+ - spec/spec_helper.rb
73
+ - spec/worker_scoreboard_spec.rb
74
+ - worker_scoreboard.gemspec
75
+ homepage: https://github.com/SpringMT/worker_scoreboard
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '2.0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.2.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: a scoreboard for monitoring status of many workers
99
+ test_files:
100
+ - spec/spec_helper.rb
101
+ - spec/worker_scoreboard_spec.rb
102
+ has_rdoc: