filesystem_queue 0.1.1 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51d0fe57ac440673ae98c9fa2a782ddfe6552450bf984dd44c4edc0d0f972e2f
4
- data.tar.gz: e61ded49f3eb2919f0da55ce20627a5d3a732c22c71bf747b64def5f42f0e2a4
3
+ metadata.gz: 7954b5b7e75219071fbf43cb6c92efa52477a933a2e2238e189ee67dc8cc87ae
4
+ data.tar.gz: 5b253de47b288f393474f5ed225429ec48132856e3f1f2b45c040b2dc506286e
5
5
  SHA512:
6
- metadata.gz: 7ecb0a4780632dcedcbe33593460c9b827c4bc1402b967fe9cd010ca3cbb2ab97f4e7bcdcbe33f707caf7bf8a90d964c65f8e773cf806f2a2e3436e203398c85
7
- data.tar.gz: 73b113cb15f2cd5eb285565ceb82c62b8d3b0f6180c49c75c374228becd4ba0f1877dc49794cc01b7ca0e3b4442b43614d229e21f093e43739e4c7ab84da2eed
6
+ metadata.gz: 4cfbee5995cbcb04f1f5757ee1415744ee2b236d95864c94930c43c50234cd6080d8554b3e06726dba95203292cef1760e65b40afbba1445c4479c1d09500fbc
7
+ data.tar.gz: 43dcdde986b435fdf1b3c06ee15f598a0b95406d62ecea8754e32b1c8a7d10fb243757df18c83cd0486bd909a408b0eb06a18ae35773138836d76cea697e9e0c
data/.rubocop.yml CHANGED
@@ -3,7 +3,6 @@ AllCops:
3
3
 
4
4
  Style/StringLiterals:
5
5
  Enabled: true
6
- EnforcedStyle: double_quotes
7
6
 
8
7
  Style/StringLiteralsInInterpolation:
9
8
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,8 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2024-09-20
4
+ - Added `reenqueue_failed_jobs` method to move failed jobs back to the queue
5
+ - Added `reenqueue_completed_jobs` method to move completed jobs back to the queue
6
+
7
+ ## [0.2.0] - 2024-09-16
8
+ - Replaced old index for an in-memory index for job tracking
9
+ - Added `cleanup` method to delete files and directories created by the queue
10
+
3
11
  ## [0.1.1] - 2024-09-13
4
12
  - Added unit tests
5
13
  - Fixed Github Actions
6
14
  - Minor refactors
15
+
7
16
  ## [0.1.0] - 2024-09-12
8
17
  - Initial release
data/Gemfile CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in filesystem_queue.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
8
+ gem 'rake', '~> 13.0'
9
9
 
10
- gem "minitest", "~> 5.0"
10
+ gem 'minitest', '~> 5.0'
11
11
 
12
- gem "rubocop", "~> 1.21"
12
+ gem 'rubocop', '~> 1.21'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- filesystem_queue (0.1.1)
4
+ filesystem_queue (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -14,9 +14,11 @@
14
14
  - **Persistence**: Jobs are stored on the filesystem, ensuring they are not lost between application restarts.
15
15
  - **Minimal Overhead**: No need for external dependencies or services.
16
16
  - **Ease of Use**: Simple API for enqueuing and dequeuing jobs.
17
- - **Improved Performance**: Enhances filesystem performance by using an index file that keeps track of files by the time they are written in the queue.
18
- - **Tailored for Local Use**: This system is designed for local use with a single consumer (at the moment).
19
- - **Job Management**: Completed and failed jobs are tracked in separate folders for easy management.
17
+ - **In-Memory Index**: Uses an in-memory index for tracking jobs, improving performance by reducing file I/O operations.
18
+ - **Cleanup Method**: Provides a method to delete all files and directories created by the queue.
19
+ - **Queue Size Methods**: Includes methods to get the size of the queue and the number of failed jobs.
20
+ - **Tailored for Local Use**: This system is optimized for local use with a single consumer. If you are looking for a multiple consumer approach you should be looking for larger distributed solutions such as Resque or other distributed Queue systems.
21
+ - **Job Management**: Once a job is dequeued, it's your responsabilty to flag it as `Completed` or `Failed`. Make sure you have fault tolerant logic in your worker to ensure this step. Completed and failed jobs are tracked in separate folders for easy management.
20
22
 
21
23
  ## Installation
22
24
 
@@ -72,6 +74,18 @@ Returns the number of jobs currently in the queue.
72
74
  - **Returns**:
73
75
  - `Integer`: The number of jobs in the queue.
74
76
 
77
+ ### `reenqueue_failed_jobs`
78
+
79
+ Moves all failed jobs back to the queue for reprocessing.
80
+
81
+ ### `reenqueue_completed_jobs`
82
+
83
+ Moves all completed jobs back to the queue for reprocessing.
84
+
85
+ ### `cleanup`
86
+
87
+ Removes all files and directories created by the queue.
88
+
75
89
  ## Usage
76
90
 
77
91
  ```ruby
@@ -117,6 +131,15 @@ puts 'Queue is empty'
117
131
  # Check on failed jobs
118
132
  puts "Queue size: #{queue.size}"
119
133
  puts "Failed jobs: #{queue.failed_size}"
134
+
135
+ # Reenqueue all failed jobs back to the queue
136
+ queue.reenqueue_failed_jobs
137
+
138
+ # Reenqueue all completed jobs back to the queue
139
+ queue.reenqueue_completed_jobs
140
+
141
+ # Cleanup all files and directories created by the queue
142
+ queue.cleanup
120
143
  ```
121
144
 
122
145
  ## Error Handling
data/Rakefile CHANGED
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
5
 
6
6
  Rake::TestTask.new(:test) do |t|
7
- t.libs << "test"
8
- t.libs << "lib"
9
- t.test_files = FileList["test/**/test_*.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/test_*.rb']
10
10
  end
11
11
 
12
- require "rubocop/rake_task"
12
+ require 'rubocop/rake_task'
13
13
 
14
14
  RuboCop::RakeTask.new
15
15
 
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "lib/filesystem_queue/version"
3
+ require_relative 'lib/filesystem_queue/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "filesystem_queue"
6
+ spec.name = 'filesystem_queue'
7
7
  spec.version = FilesystemQueue::VERSION
8
- spec.authors = ["Carlos Westman"]
9
- spec.email = ["carloswestman@gmail.com"]
8
+ spec.authors = ['Carlos Westman']
9
+ spec.email = ['carloswestman@gmail.com']
10
10
 
11
- spec.summary = "A persistent queue system based on the local filesystem"
12
- spec.description = "FilesystemQueue is a Ruby gem that provides a persistent queue system "\
13
- "using the local filesystem.It allows you to enqueue and dequeue jobs, and keeps track of completed and failed jobs."
14
- spec.homepage = "https://github.com/carloswestman/filesystem_queue"
15
- spec.license = "MIT"
16
- spec.required_ruby_version = ">= 2.6.0"
11
+ spec.summary = 'A persistent queue system based on the local filesystem'
12
+ spec.description = 'FilesystemQueue is a Ruby gem that provides a persistent queue system '\
13
+ 'using the local filesystem.It allows you to enqueue and dequeue jobs, and keeps track of completed and failed jobs.'
14
+ spec.homepage = 'https://github.com/carloswestman/filesystem_queue'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 2.6.0'
17
17
 
18
- spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
19
19
 
20
- spec.metadata["homepage_uri"] = spec.homepage
21
- spec.metadata["source_code_uri"] = spec.homepage
22
- spec.metadata["changelog_uri"] = "https://github.com/carloswestman/filesystem_queue/blob/main/CHANGELOG.md"
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] = spec.homepage
22
+ spec.metadata['changelog_uri'] = 'https://github.com/carloswestman/filesystem_queue/blob/main/CHANGELOG.md'
23
23
 
24
24
  # Specify which files should be added to the gem when it is released.
25
25
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
29
29
  end
30
30
  end
31
- spec.bindir = "exe"
31
+ spec.bindir = 'exe'
32
32
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
- spec.require_paths = ["lib"]
33
+ spec.require_paths = ['lib']
34
34
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FilesystemQueue
4
- VERSION = "0.1.1"
4
+ VERSION = '0.3.0'
5
5
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
- require "fileutils"
5
- require_relative "filesystem_queue/version"
3
+ require 'json'
4
+ require 'fileutils'
5
+ require_relative 'filesystem_queue/version'
6
6
 
7
7
  module FilesystemQueue
8
8
  class Error < StandardError; end
@@ -12,27 +12,29 @@ module FilesystemQueue
12
12
  class Queue
13
13
  def initialize(queue_dir)
14
14
  @queue_dir = queue_dir
15
- @jobs_dir = File.join(@queue_dir, "jobs")
16
- @completed_dir = File.join(@queue_dir, "completed")
17
- @failed_dir = File.join(@queue_dir, "failed")
18
- @index_file = File.join(@queue_dir, "index.txt")
15
+ @jobs_dir = File.join(@queue_dir, 'jobs')
16
+ @completed_dir = File.join(@queue_dir, 'completed')
17
+ @failed_dir = File.join(@queue_dir, 'failed')
19
18
 
20
19
  [@jobs_dir, @completed_dir, @failed_dir].each do |dir|
21
20
  FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
22
21
  end
23
- FileUtils.touch(@index_file) unless File.exist?(@index_file)
22
+
23
+ @index = rebuild_index
24
24
  end
25
25
 
26
26
  def enqueue(job)
27
27
  timestamp = Time.now.to_f.to_s
28
28
  job_file = File.join(@jobs_dir, "job_#{timestamp}.json")
29
29
  File.write(job_file, job.to_json)
30
- File.open(@index_file, "a") { |f| f.puts(job_file) }
30
+ @index << job_file
31
31
  end
32
32
 
33
33
  def dequeue
34
- job_file = extract_job_file_from_index
35
- return nil unless job_file && File.exist?(job_file)
34
+ return nil if @index.empty?
35
+
36
+ job_file = @index.shift
37
+ return nil unless File.exist?(job_file)
36
38
 
37
39
  job_data = JSON.parse(File.read(job_file), symbolize_names: true)
38
40
  [job_file, job_data]
@@ -47,33 +49,56 @@ module FilesystemQueue
47
49
  end
48
50
 
49
51
  def size
50
- File.readlines(@index_file).size
52
+ @index.size
51
53
  end
52
54
 
53
55
  def failed_size
54
- Dir[File.join(@failed_dir, "*")].count { |file| File.file?(file) }
56
+ Dir[File.join(@failed_dir, '*')].count { |file| File.file?(file) }
57
+ end
58
+
59
+ def retry_failed_jobs
60
+ failed_jobs = Dir.glob(File.join(@failed_dir, '*.json'))
61
+ failed_jobs.each do |job_file|
62
+ new_job_file = File.join(@jobs_dir, File.basename(job_file))
63
+ FileUtils.mv(job_file, new_job_file)
64
+ @index << new_job_file
65
+ end
66
+ end
67
+
68
+ def reenqueue_failed_jobs
69
+ reenqueue_jobs(@failed_dir)
70
+ end
71
+
72
+ def reenqueue_completed_jobs
73
+ reenqueue_jobs(@completed_dir)
74
+ end
75
+
76
+ # CAUTION: Cleanup the queue directory, removing all files and directories
77
+ def cleanup
78
+ [@jobs_dir, @completed_dir, @failed_dir].each do |dir|
79
+ FileUtils.rm_rf(dir)
80
+ end
81
+ FileUtils.rm_rf(@queue_dir)
55
82
  end
56
83
 
57
84
  private
58
85
 
86
+ def rebuild_index
87
+ Dir.glob(File.join(@jobs_dir, '*.json')).sort
88
+ end
89
+
59
90
  def move_job(job_file, target_dir)
60
91
  FileUtils.mv(job_file, target_dir)
61
- rescue StandardError => e
62
- puts "Failed to move job file: #{e.message}"
92
+ @index.delete(job_file)
63
93
  end
64
94
 
65
- def extract_job_file_from_index
66
- job_file = nil
67
- File.open(@index_file, "r+") do |f|
68
- lines = f.each_line.to_a
69
- return nil if lines.empty?
70
-
71
- job_file = lines.shift.strip
72
- f.rewind
73
- f.write(lines.join)
74
- f.truncate(f.pos)
95
+ def reenqueue_jobs(source_dir)
96
+ job_files = Dir.glob(File.join(source_dir, '*.json'))
97
+ job_files.each do |job_file|
98
+ new_job_file = File.join(@jobs_dir, File.basename(job_file))
99
+ FileUtils.mv(job_file, new_job_file)
100
+ @index << new_job_file
75
101
  end
76
- job_file
77
102
  end
78
103
  end
79
104
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filesystem_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Westman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-13 00:00:00.000000000 Z
11
+ date: 2024-09-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: FilesystemQueue is a Ruby gem that provides a persistent queue system
14
14
  using the local filesystem.It allows you to enqueue and dequeue jobs, and keeps