fasten 0.14.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c6405a7b032ff8dd2e980a6f05ae4bf6966f1d89fc8348b992ffdffaa08929e
4
- data.tar.gz: a25985b8c478ff074f8500bf2be3ee5828a74f684192b70060d83c0bb5b66c38
3
+ metadata.gz: 93858ac8aab1bd5bbbb63aaf5475be37beaf50f43e4b6677822558ae21fdc024
4
+ data.tar.gz: 0bce3109d9d5aa7499746fe298427d40e94e6305a617e5b5ac6f321e1c808755
5
5
  SHA512:
6
- metadata.gz: f69b415d2927caafda5db2079457804e9c1d995f5ce8a10fe107f19451beca3991a5ee67acaab0af1c8d5fd59783565958d973834ce35b35e772690f60473d49
7
- data.tar.gz: 0b7ea199939c5fef57191f054ab681a96295d63b2d6bc178ace6246c8a397f340c417a0146a83bc981a395ec98cfd2a8912fa5b680158cfa6502c8dda5b8034b
6
+ metadata.gz: 740fc94594c962bb8decf84dafc2c4952db90c4ccf8bccb6522a3920d0621ebb81dfe5a979a32f862baca1d0de4e9d56a5fad550614bd363bc1784e30267758e
7
+ data.tar.gz: fff1959d04192828f7c44e6c29fcf813c39877f34f719921eb0bd672eb66772f78b51a6410f3c06baa69ee64c7b12eda5dbf88d9f29fadd289f2b599a03d8e51
data/.gitignore CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ # custom ignores
12
14
  /fasten/log
13
15
  /demo/fasten/log
14
16
  *.testfile
data/.rubocop.yml CHANGED
@@ -1,4 +1,4 @@
1
- Metrics/LineLength:
1
+ Layout/LineLength:
2
2
  Max: 160
3
3
  Style/Documentation:
4
4
  Enabled: false
@@ -23,10 +23,14 @@ Style:
23
23
  Metrics/AbcSize:
24
24
  Max: 25
25
25
  Metrics/MethodLength:
26
- Max: 15
26
+ Max: 20
27
27
  Metrics/ParameterLists:
28
28
  Max: 8
29
- Layout/AlignHash:
29
+ Layout/HashAlignment:
30
30
  EnforcedHashRocketStyle: table
31
31
  Style/FormatStringToken:
32
32
  Enabled: false
33
+
34
+ AllCops:
35
+ NewCops: enable
36
+ TargetRubyVersion: 3.0
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.6.4
1
+ ruby-2.6.6
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 2.6.4
1
+ ruby 3.0.2
data/.travis.yml CHANGED
@@ -3,5 +3,5 @@ sudo: false
3
3
  language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
- - 2.5.1
7
- before_install: gem install bundler -v 1.16.4
6
+ - 2.7.2
7
+ before_install: gem install bundler -v 2.1.4
data/CODE_OF_CONDUCT.md CHANGED
@@ -68,7 +68,7 @@ members of the project's leadership.
68
68
  ## Attribution
69
69
 
70
70
  This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
72
 
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -4,3 +4,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in fasten.gemspec
6
6
  gemspec
7
+
8
+ gem 'os'
9
+ gem 'rake', '~> 12.0'
10
+ gem 'rspec', '~> 3.0'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fasten (0.14.0)
4
+ fasten (0.18.0)
5
5
  binding_of_caller
6
6
  hirb
7
7
  os
@@ -10,59 +10,70 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- ast (2.4.0)
14
- binding_of_caller (0.8.0)
13
+ ast (2.4.2)
14
+ binding_of_caller (1.0.0)
15
15
  debug_inspector (>= 0.0.1)
16
- coderay (1.1.2)
17
- curses (1.3.1)
18
- debug_inspector (0.0.3)
19
- diff-lcs (1.3)
16
+ coderay (1.1.3)
17
+ curses (1.4.2)
18
+ debug_inspector (1.1.0)
19
+ diff-lcs (1.4.4)
20
20
  hirb (0.7.3)
21
- jaro_winkler (1.5.3)
22
- method_source (0.9.2)
23
- os (1.0.1)
24
- parallel (1.17.0)
25
- parser (2.6.5.0)
26
- ast (~> 2.4.0)
27
- pry (0.12.2)
28
- coderay (~> 1.1.0)
29
- method_source (~> 0.9.0)
21
+ method_source (1.0.0)
22
+ os (1.1.4)
23
+ parallel (1.21.0)
24
+ parser (3.0.2.0)
25
+ ast (~> 2.4.1)
26
+ pry (0.14.1)
27
+ coderay (~> 1.1)
28
+ method_source (~> 1.0)
30
29
  rainbow (3.0.0)
31
- rake (10.5.0)
32
- rspec (3.8.0)
33
- rspec-core (~> 3.8.0)
34
- rspec-expectations (~> 3.8.0)
35
- rspec-mocks (~> 3.8.0)
36
- rspec-core (3.8.2)
37
- rspec-support (~> 3.8.0)
38
- rspec-expectations (3.8.5)
30
+ rake (12.3.3)
31
+ regexp_parser (2.1.1)
32
+ rexml (3.2.5)
33
+ rspec (3.10.0)
34
+ rspec-core (~> 3.10.0)
35
+ rspec-expectations (~> 3.10.0)
36
+ rspec-mocks (~> 3.10.0)
37
+ rspec-core (3.10.1)
38
+ rspec-support (~> 3.10.0)
39
+ rspec-expectations (3.10.1)
39
40
  diff-lcs (>= 1.2.0, < 2.0)
40
- rspec-support (~> 3.8.0)
41
- rspec-mocks (3.8.2)
41
+ rspec-support (~> 3.10.0)
42
+ rspec-mocks (3.10.2)
42
43
  diff-lcs (>= 1.2.0, < 2.0)
43
- rspec-support (~> 3.8.0)
44
- rspec-support (3.8.3)
45
- rubocop (0.75.0)
46
- jaro_winkler (~> 1.5.1)
44
+ rspec-support (~> 3.10.0)
45
+ rspec-support (3.10.3)
46
+ rubocop (1.22.3)
47
47
  parallel (~> 1.10)
48
- parser (>= 2.6)
48
+ parser (>= 3.0.0.0)
49
49
  rainbow (>= 2.2.2, < 4.0)
50
+ regexp_parser (>= 1.8, < 3.0)
51
+ rexml
52
+ rubocop-ast (>= 1.12.0, < 2.0)
50
53
  ruby-progressbar (~> 1.7)
51
- unicode-display_width (>= 1.4.0, < 1.7)
52
- ruby-progressbar (1.10.1)
53
- unicode-display_width (1.6.0)
54
+ unicode-display_width (>= 1.4.0, < 3.0)
55
+ rubocop-ast (1.12.0)
56
+ parser (>= 3.0.1.1)
57
+ rubocop-rake (0.6.0)
58
+ rubocop (~> 1.0)
59
+ rubocop-rspec (2.5.0)
60
+ rubocop (~> 1.19)
61
+ ruby-progressbar (1.11.0)
62
+ unicode-display_width (2.1.0)
54
63
 
55
64
  PLATFORMS
56
65
  ruby
57
66
 
58
67
  DEPENDENCIES
59
- bundler (~> 1.17.1)
60
68
  curses
61
69
  fasten!
70
+ os
62
71
  pry
63
- rake (~> 10.0)
72
+ rake (~> 12.0)
64
73
  rspec (~> 3.0)
65
74
  rubocop
75
+ rubocop-rake
76
+ rubocop-rspec
66
77
 
67
78
  BUNDLED WITH
68
- 1.17.3
79
+ 2.2.22
data/README.md CHANGED
@@ -47,7 +47,7 @@ It has been released so people can try it and make feature requests, comments an
47
47
  - [x] Console is the default if STDOUT/STDIN is not a tty
48
48
  - [x] Display each task as is being finished
49
49
  - [ ] Calculate ETA, assuming all tasks take same time
50
- - [ ] Calculate ETA, based on saved tasks statistics
50
+ - [x] Calculate ETA, based on saved tasks statistics
51
51
 
52
52
 
53
53
  ### CLI
data/fasten.gemspec CHANGED
@@ -1,6 +1,4 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'fasten/version'
1
+ require_relative 'lib/fasten/version'
4
2
  require 'os'
5
3
 
6
4
  Gem::Specification.new do |spec|
@@ -13,29 +11,31 @@ Gem::Specification.new do |spec|
13
11
  spec.description = 'Fasten your seatbelts! Run jobs in parallel, intelligently.'
14
12
  spec.homepage = 'https://github.com/a0/a0-fasten-ruby/'
15
13
  spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.0.2')
15
+
16
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/a0/a0-fasten-ruby/CHANGELOG.md'
16
21
 
17
22
  # Specify which files should be added to the gem when it is released.
18
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|demo)/}) }
21
26
  end
22
27
  spec.bindir = 'exe'
23
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
29
  spec.require_paths = ['lib']
25
30
 
26
- spec.add_development_dependency 'bundler', '~> 1.17.1'
27
31
  spec.add_development_dependency 'curses' unless OS.windows?
28
32
  spec.add_development_dependency 'pry'
29
- spec.add_development_dependency 'rake', '~> 10.0'
30
- spec.add_development_dependency 'rspec', '~> 3.0'
31
33
  spec.add_development_dependency 'rubocop'
34
+ spec.add_development_dependency 'rubocop-rake'
35
+ spec.add_development_dependency 'rubocop-rspec'
32
36
 
33
37
  spec.add_runtime_dependency 'binding_of_caller'
34
38
  spec.add_runtime_dependency 'hirb'
35
39
  spec.add_runtime_dependency 'os'
36
40
  spec.add_runtime_dependency 'parallel'
37
-
38
- raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless spec.respond_to?(:metadata)
39
-
40
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
41
41
  end
@@ -35,13 +35,13 @@ module Fasten
35
35
 
36
36
  require 'fasten/ui/curses'
37
37
 
38
- @default_ui_mode = STDIN.tty? && STDOUT.tty? ? :curses : :console
38
+ @default_ui_mode = $stdin.tty? && $stdout.tty? ? :curses : :console
39
39
  rescue StandardError, LoadError
40
40
  @default_ui_mode = :console
41
41
  end
42
42
 
43
43
  def default_developer
44
- STDIN.tty? && STDOUT.tty?
44
+ $stdin.tty? && $stdout.tty?
45
45
  end
46
46
 
47
47
  def default_priority
data/lib/fasten/runner.rb CHANGED
@@ -28,7 +28,7 @@ module Fasten
28
28
  @tasks = TaskManager.new(targets: options[:targets] || [], runner: self)
29
29
  @workers = []
30
30
 
31
- reconfigure(options)
31
+ reconfigure(**options)
32
32
  end
33
33
 
34
34
  def reconfigure(**options)
@@ -37,11 +37,12 @@ module Fasten
37
37
  end
38
38
 
39
39
  initialize_stats
40
- initialize_logger
41
40
  end
42
41
 
43
42
  def task(name, **opts, &block)
44
- tasks << task = Task.new(name: name, **opts, block: block)
43
+ opts[:name] = name
44
+ opts[:block] = block
45
+ tasks << task = Task.new(**opts)
45
46
 
46
47
  task
47
48
  end
@@ -51,6 +52,8 @@ module Fasten
51
52
  end
52
53
 
53
54
  def perform
55
+ initialize_logger
56
+ StdThreadProxy.install if use_threads
54
57
  self.state = :RUNNING
55
58
  log_ini self, running_counters
56
59
  load_stats
@@ -67,13 +70,15 @@ module Fasten
67
70
 
68
71
  stats_summary if summary
69
72
  ensure
73
+ StdThreadProxy.uninstall if use_threads
74
+ close_logger
70
75
  save_stats
71
76
  end
72
77
 
73
78
  def touch_task_logs
74
- FileUtils.mkdir_p "#{runner.fasten_dir}/log/task/"
79
+ FileUtils.mkdir_p "#{fasten_dir}/log/task/"
75
80
  tasks.each do |task|
76
- path = "#{runner.fasten_dir}/log/task/#{task.name}.log"
81
+ path = "#{fasten_dir}/log/task/#{task.name}.log"
77
82
  puts "Fasten: creating log #{path}"
78
83
  FileUtils.touch path
79
84
  end
@@ -108,7 +113,7 @@ module Fasten
108
113
  dispatch_pending_tasks
109
114
  end
110
115
 
111
- break if tasks.no_running? && tasks.no_waiting? || state == :QUIT
116
+ break if (tasks.no_running? && tasks.no_waiting?) || state == :QUIT
112
117
  end
113
118
 
114
119
  remove_all_workers
@@ -126,7 +131,7 @@ module Fasten
126
131
  end
127
132
 
128
133
  def should_wait_for_running_tasks?
129
- tasks.running? && (tasks.no_waiting? || tasks.failed? || %i[PAUSING QUITTING].include?(state)) || tasks.running.map(&:weight).sum >= jobs
134
+ (tasks.running? && (tasks.no_waiting? || tasks.failed? || %i[PAUSING QUITTING].include?(state))) || tasks.running.map(&:weight).sum >= jobs
130
135
  end
131
136
 
132
137
  def wait_for_running_tasks
@@ -228,7 +233,7 @@ module Fasten
228
233
  end
229
234
 
230
235
  def find_or_create_worker(worker_class:)
231
- worker = workers.find { |item| item.class == worker_class && item.running_task.nil? }
236
+ worker = workers.find { |item| item.instance_of?(worker_class) && item.running_task.nil? }
232
237
 
233
238
  unless worker
234
239
  @worker_id = (@worker_id || 0) + 1
@@ -1,24 +1,28 @@
1
1
  module Fasten
2
2
  class StdThreadProxy
3
- def initialize(original)
4
- @original = original
3
+ attr_reader :fasten_original
4
+
5
+ def initialize(fasten_original)
6
+ @fasten_original = fasten_original
5
7
  end
6
8
 
7
- def respond_to?(name, include_private = false)
8
- target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @original
9
- target.send :respond_to?, name, include_private
9
+ def respond_to?(*args)
10
+ target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @fasten_original
11
+ target.send :respond_to?, *args
10
12
  end
11
13
 
12
14
  private
13
15
 
14
- def respond_to_missing?(name, include_private = false)
15
- target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @original
16
- target.send :respond_to_missing?, name, include_private
16
+ def respond_to_missing?(*args)
17
+ target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @fasten_original
18
+ target.send :respond_to_missing?, *args
17
19
  end
18
20
 
19
- def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissingSuper
20
- target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @original
21
+ def method_missing(method, *args, &block)
22
+ target = Thread.current[:FASTEN_STD_THREAD_PROXY] || @fasten_original
21
23
  target.send method, *args, &block
24
+ rescue StandardError => e
25
+ raise e
22
26
  end
23
27
 
24
28
  class << self
@@ -28,8 +32,9 @@ module Fasten
28
32
  oldverbose = $VERBOSE
29
33
  $VERBOSE = nil
30
34
 
31
- Object.const_set :STDOUT, StdThreadProxy.new(STDOUT)
32
- Object.const_set :STDERR, StdThreadProxy.new(STDERR)
35
+ Object.const_set :STDOUT, StdThreadProxy.new(STDOUT) # rubocop:disable Style/GlobalStdStream
36
+ Object.const_set :STDERR, StdThreadProxy.new(STDERR) # rubocop:disable Style/GlobalStdStream
37
+
33
38
  $stdout = StdThreadProxy.new $stdout
34
39
  $stderr = StdThreadProxy.new $stderr
35
40
 
@@ -49,7 +54,18 @@ module Fasten
49
54
  def uninstall
50
55
  return unless @installed
51
56
 
57
+ oldverbose = $VERBOSE
58
+ $VERBOSE = nil
59
+
60
+ Object.const_set :STDOUT, STDOUT.fasten_original if STDOUT.is_a? StdThreadProxy # rubocop:disable Style/GlobalStdStream
61
+ Object.const_set :STDERR, STDERR.fasten_original if STDERR.is_a? StdThreadProxy # rubocop:disable Style/GlobalStdStream
62
+
63
+ $stdout = $stdout.fasten_original if $stdout.is_a? StdThreadProxy
64
+ $stderr = $stderr.fasten_original if $stderr.is_a? StdThreadProxy
65
+
52
66
  @installed = nil
67
+ ensure
68
+ $VERBOSE = oldverbose
53
69
  end
54
70
  end
55
71
  end
@@ -75,27 +75,24 @@ module Fasten
75
75
  end
76
76
 
77
77
  def redirect_std(path)
78
- @saved_stdout_constant = STDOUT.clone
79
- @saved_stderr_constant = STDERR.clone
78
+ @saved_stdout_constant ||= $stdout.clone
79
+ @saved_stderr_constant ||= $stderr.clone
80
80
 
81
81
  FileUtils.mkdir_p File.dirname(path)
82
82
  @redirect_log = File.new path, 'a'
83
83
  @redirect_log.sync = true
84
84
 
85
- STDOUT.reopen @redirect_log
86
- STDERR.reopen @redirect_log
85
+ $stdout.reopen @redirect_log
86
+ $stderr.reopen @redirect_log
87
87
 
88
- logger.reopen($stdout)
88
+ logger.reopen(@redirect_log)
89
89
  end
90
90
 
91
91
  def restore_std
92
92
  @redirect_log.close
93
93
 
94
- STDOUT.reopen @saved_stdout_constant
95
- STDERR.reopen @saved_stderr_constant
96
-
97
- @saved_stdout_constant = nil
98
- @saved_stderr_constant = nil
94
+ $stdout.reopen @saved_stdout_constant
95
+ $stderr.reopen @saved_stderr_constant
99
96
  end
100
97
  end
101
98
  end
@@ -26,14 +26,18 @@ module Fasten
26
26
  if log_file
27
27
  self.log_file = log_file
28
28
  else
29
- log_path ||= "#{fasten_dir}/log/#{kind}/#{name}.log"
30
- FileUtils.mkdir_p File.dirname(log_path)
31
- self.log_file = File.new(log_path, 'a')
32
- self.log_file.sync = true
29
+ self.log_file ||= "#{fasten_dir}/log/#{kind}/#{name}.log"
30
+ FileUtils.mkdir_p File.dirname(self.log_file)
33
31
  end
32
+
33
+ close_logger
34
34
  self.logger = ::Logger.new self.log_file, level: Fasten.logger.level, progname: Fasten.logger.progname
35
35
  end
36
36
 
37
+ def close_logger
38
+ logger.close if logger.is_a? ::Logger
39
+ end
40
+
37
41
  def log_ini(object, message = nil)
38
42
  object.ini ||= Time.new
39
43
  log_info "Ini #{object.state} #{object.class} #{object} #{message}"
@@ -51,7 +55,7 @@ end
51
55
 
52
56
  Fasten.logger ||=
53
57
  begin
54
- Logger.new STDOUT, level: Logger::DEBUG, progname: $PROGRAM_NAME
58
+ Logger.new $stdout, level: Logger::DEBUG, progname: $PROGRAM_NAME
55
59
  rescue StandardError
56
60
  nil
57
61
  end
@@ -56,19 +56,27 @@ module Fasten
56
56
 
57
57
  def deps_str
58
58
  if is_a? Fasten::Task
59
- if after.is_a? Array
60
- after.sort_by do |task|
61
- task.is_a?(Fasten::Task) ? task.name : task
62
- end&.join(', ')
63
- else
64
- after
65
- end
59
+ deps_str_task
66
60
  elsif is_a? Fasten::Runner
67
- tasks.sort_by(&:name).map do |task|
68
- [task.name, task.deps_str].compact.join(': ')
69
- end.join("\n")
61
+ deps_str_runner
70
62
  end
71
63
  end
64
+
65
+ def deps_str_task
66
+ if after.is_a? Array
67
+ after.sort_by do |task|
68
+ task.is_a?(Fasten::Task) ? task.name : task
69
+ end&.join(', ')
70
+ else
71
+ after
72
+ end
73
+ end
74
+
75
+ def deps_str_runner
76
+ tasks.sort_by(&:name).map do |task|
77
+ [task.name, task.deps_str].compact.join(': ')
78
+ end.join("\n")
79
+ end
72
80
  end
73
81
  end
74
82
  end
@@ -5,8 +5,8 @@ require 'fileutils'
5
5
  module Fasten
6
6
  module Support
7
7
  module Stats
8
- attr_writer :stats_data, :stats_entries
9
- attr_reader :stats_path
8
+ # attr_writer :stats_data, :stats_entries
9
+ # attr_reader :stats_path
10
10
 
11
11
  def initialize_stats
12
12
  return unless stats
@@ -20,7 +20,7 @@ module Fasten
20
20
  def load_stats
21
21
  return unless @stats_path && File.exist?(@stats_path)
22
22
 
23
- self.stats_data = []
23
+ @stats_data = []
24
24
  CSV.foreach(@stats_path, headers: true, converters: [:all]) do |row|
25
25
  stats_data << row.to_h
26
26
  end
@@ -54,7 +54,6 @@ module Fasten
54
54
  def restore_std
55
55
  @redirect_log&.close
56
56
  StdThreadProxy.thread_io = nil
57
- logger.reopen(log_file)
58
57
  end
59
58
  end
60
59
  end
@@ -6,7 +6,7 @@ module Fasten
6
6
  def ui
7
7
  require 'fasten/ui/curses'
8
8
 
9
- @ui ||= if ui_mode.to_s == 'curses' && STDIN.tty? && STDOUT.tty?
9
+ @ui ||= if ui_mode.to_s == 'curses' && $stdin.tty? && $stdout.tty?
10
10
  Fasten::UI::Curses.new(runner: self)
11
11
  else
12
12
  Fasten::UI::Console.new(runner: self)
@@ -5,15 +5,16 @@ module Fasten
5
5
  module Yaml
6
6
  def load_yaml(path)
7
7
  items = YAML.safe_load(File.read(path)).each do |name, params|
8
- if params.is_a? String
8
+ case params
9
+ when String
9
10
  params = { after: params }
10
- elsif params.is_a? Hash
11
+ when Hash
11
12
  transform_params(params)
12
13
  else
13
14
  params = {}
14
15
  end
15
16
 
16
- task name, params
17
+ task name, **params
17
18
  end
18
19
 
19
20
  log_info "Loaded #{items.count} tasks from #{path}"
@@ -38,15 +39,16 @@ module Fasten
38
39
  protected
39
40
 
40
41
  def transform_params(params)
41
- params.keys.each do |k|
42
- val = params[k]
42
+ keys = params.keys
43
+
44
+ keys.each do |key|
45
+ val = params.delete key
43
46
 
44
47
  if val.is_a?(String) && (match = %r{^/(.+)/$}.match(val))
45
48
  val = Regexp.new(match[1])
46
49
  end
47
50
 
48
- params[k.to_sym] = val
49
- params.delete(k)
51
+ params[key.to_sym] = val
50
52
  end
51
53
  end
52
54
  end
data/lib/fasten/task.rb CHANGED
@@ -4,8 +4,7 @@ module Fasten
4
4
  class Task
5
5
  include Fasten::Support::State
6
6
 
7
- attr_accessor :name, :after, :shell, :ruby, :worker_class
8
- attr_accessor :dependants, :depends, :request, :response, :worker, :run_score, :weight, :block
7
+ attr_accessor :name, :after, :shell, :ruby, :worker_class, :dependants, :depends, :request, :response, :worker, :run_score, :weight, :block
9
8
 
10
9
  def initialize(name:, shell: nil, ruby: nil, block: nil, request: nil, after: nil, weight: 1, worker_class: nil)
11
10
  self.name = name
@@ -16,6 +15,20 @@ module Fasten
16
15
  self.after = after
17
16
  self.weight = weight
18
17
  self.worker_class = worker_class
18
+
19
+ # ObjectSpace.define_finalizer(self) do
20
+ # puts "I am dying! pid: #{Process.pid} thread: #{Thread.current} TASK #{@name}"
21
+ # end
22
+
23
+ block&.object_id
24
+ # block && begin
25
+
26
+ # # puts "block_id: #{block.object_id} for task #{@name}"
27
+ # end
28
+
29
+ # block && ObjectSpace.define_finalizer(block) do
30
+ # puts "I am dying! pid: #{Process.pid} thread: #{Thread.current} TASK #{@name} BLOCK"
31
+ # end
19
32
  end
20
33
 
21
34
  def marshal_dump
@@ -24,7 +37,11 @@ module Fasten
24
37
 
25
38
  def marshal_load(data)
26
39
  @name, @state, @ini, @fin, @dif, @request, @response, @shell, @ruby, block_id, @error = data
27
- @block = ObjectSpace._id2ref block_id if block_id
40
+ @block = begin
41
+ ObjectSpace._id2ref block_id.to_i if block_id
42
+ rescue StandardError
43
+ # pass
44
+ end
28
45
 
29
46
  raise "Sorry, unable to get block for task #{self}, please try using threads" if block_id && !@block.is_a?(Proc)
30
47
  end
@@ -2,7 +2,7 @@ module Fasten
2
2
  class TaskManager < Array # rubocop:disable Metrics/ClassLength
3
3
  attr_reader :done, :failed, :pending, :running, :targets, :runner
4
4
 
5
- def initialize(targets: [], runner:)
5
+ def initialize(runner:, targets: [])
6
6
  super()
7
7
 
8
8
  @map = {}
@@ -120,6 +120,10 @@ module Fasten
120
120
  mark_needed(task)
121
121
  end
122
122
 
123
+ setup_pending
124
+ end
125
+
126
+ def setup_pending
123
127
  @pending.reject { |task| task.state == :NEED }.each do |task|
124
128
  @pending.delete task
125
129
  delete task
@@ -20,7 +20,7 @@ module Fasten
20
20
  puts <<~FIN
21
21
 
22
22
  = == === ==== ===== ====== ======= ======== ========= ==========
23
- Fasten your seatbelts! #{'💺' * jobs} #{runner.use_threads ? 'threads' : 'processes'}
23
+ Fasten your seatbelts! #{'💺' * jobs} #{jobs} #{runner.use_threads ? 'threads' : 'processes'} #{tasks.count} tasks
24
24
 
25
25
  #{name}
26
26
  FIN
@@ -48,9 +48,29 @@ module Fasten
48
48
  def display_task_message(orig, old, message)
49
49
  return unless old.count != orig.count
50
50
 
51
+ elapsed_str = hformat Time.new - runner.ini
52
+
53
+ time_str = [elapsed_str, eta_str].compact.join(' ')
54
+
51
55
  (orig - old).each do |task|
52
- puts "Time: #{hformat Time.new - runner.ini} #{message} #{hformat task.dif} #{task.worker} Task #{task}"
53
56
  old << task
57
+ puts "#{count_str(old.count, tasks.count)} Time: #{time_str} #{message} #{hformat task.dif} #{task.worker} Task #{task}"
58
+ end
59
+ end
60
+
61
+ def count_str(count, total)
62
+ len = total.to_s.length
63
+ format "%#{len}d/%#{len}d", count, total
64
+ end
65
+
66
+ def eta_str
67
+ @eta_str ||= begin
68
+ @runner_last_avg = runner.last_avg
69
+ if runner.last_avg && runner.last_err
70
+ format 'ETA ≈ %s ± %.2f', hformat(runner.last_avg), runner.last_err
71
+ elsif runner.last_avg
72
+ format 'ETA ≈ %s', hformat(runner.last_avg)
73
+ end
54
74
  end
55
75
  end
56
76
  end
@@ -39,7 +39,7 @@ module Fasten
39
39
 
40
40
  def draw_title
41
41
  ui_text_aligned(0, :left, 'Fasten your seatbelts!')
42
- ui_text_aligned(0, :center, name.to_s)
42
+ ui_text_aligned(0, :center, "#{name} #{$PID}")
43
43
  ui_text_aligned(0, :right, Time.new.to_s)
44
44
  end
45
45
 
@@ -127,11 +127,12 @@ module Fasten
127
127
  end
128
128
 
129
129
  def ui_jobs_summary
130
- running_count = tasks.running.count
131
- waiting_count = tasks.waiting.count
132
- workers_count = workers.count
130
+ running = tasks.running.count
131
+ waiting = tasks.waiting.count
132
+ working = workers.count
133
+ idle = working - running
133
134
 
134
- "Procs running: #{running_count} idle: #{workers_count - running_count} waiting: #{waiting_count} #{runner.use_threads ? 'threads' : 'processes'}: #{jobs}"
135
+ "Procs running: #{running} idle: #{idle} waiting: #{waiting} #{runner.use_threads ? 'threads' : 'processes'}: #{jobs}"
135
136
  end
136
137
 
137
138
  def ui_jobs
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fasten
4
- VERSION = '0.14.0'
4
+ VERSION = '0.18.0'
5
5
  end
data/lib/fasten/worker.rb CHANGED
@@ -89,6 +89,7 @@ module Fasten
89
89
  perform_task task
90
90
  ensure
91
91
  restore_std
92
+
92
93
  logger.reopen(log_file)
93
94
  log_fin task, 'run_task'
94
95
  end
data/lib/fasten.rb CHANGED
@@ -113,7 +113,7 @@ module Fasten
113
113
 
114
114
  @options[:targets] = ARGV.to_a
115
115
 
116
- runner @options
116
+ runner **@options
117
117
  @load_path = Dir['fasten/*_fasten.rb'] if @load_path.empty?
118
118
  load_fasten @load_path
119
119
 
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fasten
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aldrin Martoq
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-28 00:00:00.000000000 Z
11
+ date: 2021-11-07 00:00:00.000000000 Z
12
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.17.1
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 1.17.1
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: curses
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -53,35 +39,35 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: rake
42
+ name: rubocop
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
- - - "~>"
45
+ - - ">="
60
46
  - !ruby/object:Gem::Version
61
- version: '10.0'
47
+ version: '0'
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - "~>"
52
+ - - ">="
67
53
  - !ruby/object:Gem::Version
68
- version: '10.0'
54
+ version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
- name: rspec
56
+ name: rubocop-rake
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - "~>"
59
+ - - ">="
74
60
  - !ruby/object:Gem::Version
75
- version: '3.0'
61
+ version: '0'
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - "~>"
66
+ - - ">="
81
67
  - !ruby/object:Gem::Version
82
- version: '3.0'
68
+ version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
- name: rubocop
70
+ name: rubocop-rspec
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
@@ -199,7 +185,9 @@ licenses:
199
185
  - MIT
200
186
  metadata:
201
187
  allowed_push_host: https://rubygems.org
202
- post_install_message:
188
+ homepage_uri: https://github.com/a0/a0-fasten-ruby/
189
+ source_code_uri: https://github.com/a0/a0-fasten-ruby/CHANGELOG.md
190
+ post_install_message:
203
191
  rdoc_options: []
204
192
  require_paths:
205
193
  - lib
@@ -207,15 +195,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
195
  requirements:
208
196
  - - ">="
209
197
  - !ruby/object:Gem::Version
210
- version: '0'
198
+ version: 3.0.2
211
199
  required_rubygems_version: !ruby/object:Gem::Requirement
212
200
  requirements:
213
201
  - - ">="
214
202
  - !ruby/object:Gem::Version
215
203
  version: '0'
216
204
  requirements: []
217
- rubygems_version: 3.0.3
218
- signing_key:
205
+ rubygems_version: 3.2.22
206
+ signing_key:
219
207
  specification_version: 4
220
208
  summary: Fasten your seatbelts! Run jobs in parallel, intelligently.
221
209
  test_files: []