From dee962f542573ee82b2ad4a2edb6b0d68e71e04a Mon Sep 17 00:00:00 2001 From: Zakir Dzhamaliddinov Date: Thu, 11 Jul 2024 17:36:56 +0300 Subject: [PATCH 1/2] Add simple examples of gem usage --- README.md | 14 +++-- examples/download_and_move_file.rb | 80 +++++++++++++++++++++++++++ examples/download_file.rb | 86 ++++++++++++++++++++++++++++++ examples/move_file.rb | 84 +++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 examples/download_and_move_file.rb create mode 100644 examples/download_file.rb create mode 100644 examples/move_file.rb diff --git a/README.md b/README.md index b904dd8..1e3eac2 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ parent function. ```ruby def create_build_and_test UberTask.run( - name: "Build and Test" + "Build and Test" default_retry_count: 1, default_retry_wait: 5.mins, retry_count: 1 @@ -73,7 +73,7 @@ On calling the `.run` method of UberTask inside this function, we add this funct #### parameters -1. name: +1. name - Default value is nil. Set the value of this parameter which signifies what the function does. @@ -107,7 +107,7 @@ We need to call this inside the `UberTask#run` method. This event is triggered w ```ruby def install_ruby UberTask.run( - name: "Install Ruby" + "Install Ruby" retry_count: 2 ) do @@ -191,6 +191,14 @@ TODO: need to come up with an appropriate example. 1. block: Pass a Ruby block that contains the code to be executed. +## Examples + +You can run some examples at `examples/` folder: + +``` +ruby examples/download_and_move_file.rb +``` + ## License The gem is available as open source under the terms of the diff --git a/examples/download_and_move_file.rb b/examples/download_and_move_file.rb new file mode 100644 index 0000000..22dc1e7 --- /dev/null +++ b/examples/download_and_move_file.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require 'uber_task' +require 'colorize' + +require_relative 'download_file' +require_relative 'move_file' + +module Examples + class DownloadAndMoveFile + def self.run(source:, download_path:, move_path:) + UberTask.run('Download and move file', retry_count: 2) do + UberTask.on_success do + UberTask.logger.info( + 'Top-level task was completed successfully!'.green, + ) + end + + UberTask.on_subtask_error do + UberTask.logger.info( + 'Unexpected subtask error can be caught on top-level task ' \ + 'and an early return can be made, ' \ + 'isn\'t that cool!?'.underline, + ) + return # Try to remove this line and see what happens! + end + + # Notice that we are passing `vital: true` option so that + # an early return can be made if task fails + begin + Examples::DownloadFile.run( + source: source, + to: download_path, + vital: true, + ) + rescue StandardError => err + UberTask.logger.info "Failed to download file -- #{err.message}" + return + end + + Examples::MoveFile.run(from: download_path, to: move_path) + end + end + end +end + +if __FILE__ == $PROGRAM_NAME + Dir.mktmpdir do |dir| + download_path = File.join(dir, 'test') + move_path = File.join(dir, 'new_path') + + puts '--- Running successfull case ---' + Examples::DownloadAndMoveFile.run( + source: VALID_FILE_URI, + download_path: download_path, + move_path: move_path, + ) + + puts "\n--- Running case which fails to download file ---\n" + Examples::DownloadAndMoveFile.run( + source: NON_EXESTENT_FILE_URI, + download_path: download_path, + move_path: move_path, + ) + + puts "\n--- Running case with invalid download path ---\n" + Examples::DownloadAndMoveFile.run( + source: VALID_FILE_URI, + download_path: '/invalid_path', + move_path: move_path, + ) + + puts "\n--- Running case with invalid move path ---\n" + Examples::DownloadAndMoveFile.run( + source: VALID_FILE_URI, + download_path: download_path, + move_path: '/invalid_path', + ) + end +end diff --git a/examples/download_file.rb b/examples/download_file.rb new file mode 100644 index 0000000..699b681 --- /dev/null +++ b/examples/download_file.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'uber_task' +require 'colorize' +require 'open-uri' +require 'tmpdir' + +VALID_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/README.md' +NON_EXESTENT_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/NON_EXISTENT.md' + +module Examples + class DownloadFile + def self.run(to:, source: VALID_FILE_URI, **task_options) + UberTask.run( + 'Download file from external source', + default_retry_wait: 3, + retry_count: 5, + vital: false, + **task_options, + ) do + UberTask.on_retry do + UberTask.logger.info( + "Retrying to download file from #{source}...".yellow, + ) + end + + UberTask.on_success do + UberTask.logger.info( + "Downloaded file #{source} and saved it at #{to}".green, + ) + end + + save_external_file!(source: source, to: to) + end + end + + def self.save_external_file!(source:, to:) + URI.parse(source).open { |io| File.write(to, io.read) } + rescue OpenURI::HTTPError => err + raise UberTask::RetryTask.new(reason: err.message) + end + private_class_method :save_external_file! + end +end + +if __FILE__ == $PROGRAM_NAME + Dir.mktmpdir do |dir| + filepath = File.join(dir, 'test') + + puts '--- Running successfull case ---' + Examples::DownloadFile.run(source: VALID_FILE_URI, to: filepath) + + puts "\n--- Running failing case with `vital: true`---\n" + begin + Examples::DownloadFile.run( + source: NON_EXESTENT_FILE_URI, + to: filepath, + vital: true, + ) + rescue StandardError + UberTask.logger.info 'Error was raised'.red + end + + puts "\n--- Running failing case with `vital: false`---\n" + Examples::DownloadFile.run( + source: NON_EXESTENT_FILE_URI, + to: filepath, + vital: false, + ) + UberTask.logger.info 'Error wasn\'t raised'.green + + puts "\n--- Running failing case with `retry_count: 1`---\n" + Examples::DownloadFile.run( + source: NON_EXESTENT_FILE_URI, + to: filepath, + retry_count: 1, + ) + + puts "\n--- Running failing case with `default_retry_wait: 0`---\n" + Examples::DownloadFile.run( + source: NON_EXESTENT_FILE_URI, + to: filepath, + default_retry_wait: 0, + ) + end +end diff --git a/examples/move_file.rb b/examples/move_file.rb new file mode 100644 index 0000000..f6dfb06 --- /dev/null +++ b/examples/move_file.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'uber_task' +require 'colorize' +require 'tmpdir' +require 'fileutils' + +module Examples + class MoveFile + def self.run(from:, to:, **task_options) + UberTask.run( + 'Download file from external source', + default_retry_wait: 1, + retry_count: 3, + vital: false, + **task_options, + ) do + UberTask.on_success do + UberTask.logger.info "Moved file from #{from} to #{to}".green + end + + UberTask.on_retry do + UberTask.logger.info( + "Retrying to move file from #{from} to #{to}...".yellow, + ) + end + + move_file!(from: from, to: to) + end + end + + def self.move_file!(from:, to:) + FileUtils.mv(from, to) + rescue Errno::ENOENT => err + raise UberTask::RetryTask.new(reason: err.message) + end + private_class_method :move_file! + end +end + +if __FILE__ == $PROGRAM_NAME + Dir.mktmpdir do |dir| + File.open(File.join(dir, 'old_path'), 'w') do |file| + file.write('test') + + puts '--- Running successfull case ---' + Examples::MoveFile.run(from: file.path, to: File.join(dir, 'new_path')) + end + + ### Notice that task has `vital: true` so error is raised + puts "\n--- Running failing case with `vital: true`---\n" + begin + Examples::MoveFile.run( + from: 'invalid_path', + to: File.join(dir, 'new_path'), + vital: true, + ) + rescue StandardError + UberTask.logger.info 'Error was raised'.red + end + + ### Notice that task has `vital: false` so error isn't raised + puts "\n--- Running failing case with `vital: false`---\n" + Examples::MoveFile.run( + from: 'invalid_path', + to: File.join(dir, 'new_path'), + vital: false, + ) + + puts "\n--- Running failing case with `retry_count: 1`---\n" + Examples::MoveFile.run( + from: 'invalid_path', + to: File.join(dir, 'new_path'), + retry_count: 1, + ) + + puts "\n--- Running failing case with `default_retry_wait: 3`---\n" + Examples::MoveFile.run( + from: 'invalid_path', + to: File.join(dir, 'new_path'), + default_retry_wait: 3, + ) + end +end From 84154c730edeb08ce5243a6d3a5a048a041f9036 Mon Sep 17 00:00:00 2001 From: Zakir Dzhamaliddinov Date: Fri, 12 Jul 2024 17:47:48 +0300 Subject: [PATCH 2/2] Review fixes --- README.md | 3 +- examples/download_and_move_file.rb | 84 ++++++++++++++++-------------- examples/download_file.rb | 69 ++++-------------------- examples/failing_task.rb | 15 ++++++ examples/move_file.rb | 51 +----------------- 5 files changed, 72 insertions(+), 150 deletions(-) create mode 100644 examples/failing_task.rb diff --git a/README.md b/README.md index 1e3eac2..e476f71 100644 --- a/README.md +++ b/README.md @@ -193,8 +193,7 @@ TODO: need to come up with an appropriate example. ## Examples -You can run some examples at `examples/` folder: - +You can find examples of gem usage at `examples/` folder: ``` ruby examples/download_and_move_file.rb ``` diff --git a/examples/download_and_move_file.rb b/examples/download_and_move_file.rb index 22dc1e7..8d2ecc6 100644 --- a/examples/download_and_move_file.rb +++ b/examples/download_and_move_file.rb @@ -2,42 +2,62 @@ require 'uber_task' require 'colorize' +require 'tmpdir' require_relative 'download_file' require_relative 'move_file' +require_relative 'failing_task' + +EXISTENT_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/README.md' +NON_EXESTENT_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/NON_EXISTENT.md' +NON_VITAL_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/NON_VITAL.md' module Examples class DownloadAndMoveFile - def self.run(source:, download_path:, move_path:) - UberTask.run('Download and move file', retry_count: 2) do + def self.run(uri:, download_path:, move_path:) + UberTask.run('Download and move file') do UberTask.on_success do UberTask.logger.info( 'Top-level task was completed successfully!'.green, ) end - UberTask.on_subtask_error do - UberTask.logger.info( - 'Unexpected subtask error can be caught on top-level task ' \ - 'and an early return can be made, ' \ - 'isn\'t that cool!?'.underline, - ) - return # Try to remove this line and see what happens! - end + UberTask.on_subtask_error do |_task, event, err| + case err + # Network errors occuring in subtasks are handled here in top-level + when OpenURI::HTTPError + UberTask.retry(reason: err, wait: 5) + # Subtasks can be skipped + when Examples::FailingTask::Error + UberTask.logger.info( + 'Encountered expected error, skipping...'.yellow, + ) - # Notice that we are passing `vital: true` option so that - # an early return can be made if task fails - begin - Examples::DownloadFile.run( - source: source, - to: download_path, - vital: true, - ) - rescue StandardError => err - UberTask.logger.info "Failed to download file -- #{err.message}" - return + UberTask.skip + else + UberTask.logger.error( + "Encountered unexpected error - #{err.message}".red, + ) + event.handled + end end + Examples::DownloadFile.run( + uri: NON_VITAL_FILE_URI, + to: download_path, + retry_count: 1, + vital: false, # execution won't stop when this task fails + ) + + Examples::FailingTask.run + + Examples::DownloadFile.run( + uri: uri, + to: download_path, + retry_count: 3, + vital: true, # execution will stop if this task fails + ) + Examples::MoveFile.run(from: download_path, to: move_path) end end @@ -46,35 +66,21 @@ def self.run(source:, download_path:, move_path:) if __FILE__ == $PROGRAM_NAME Dir.mktmpdir do |dir| - download_path = File.join(dir, 'test') - move_path = File.join(dir, 'new_path') + download_path = File.join(dir, 'download_path') + move_path = File.join(dir, 'move_path') puts '--- Running successfull case ---' Examples::DownloadAndMoveFile.run( - source: VALID_FILE_URI, + uri: EXISTENT_FILE_URI, download_path: download_path, move_path: move_path, ) puts "\n--- Running case which fails to download file ---\n" Examples::DownloadAndMoveFile.run( - source: NON_EXESTENT_FILE_URI, + uri: NON_EXESTENT_FILE_URI, download_path: download_path, move_path: move_path, ) - - puts "\n--- Running case with invalid download path ---\n" - Examples::DownloadAndMoveFile.run( - source: VALID_FILE_URI, - download_path: '/invalid_path', - move_path: move_path, - ) - - puts "\n--- Running case with invalid move path ---\n" - Examples::DownloadAndMoveFile.run( - source: VALID_FILE_URI, - download_path: download_path, - move_path: '/invalid_path', - ) end end diff --git a/examples/download_file.rb b/examples/download_file.rb index 699b681..68aa2f4 100644 --- a/examples/download_file.rb +++ b/examples/download_file.rb @@ -3,84 +3,35 @@ require 'uber_task' require 'colorize' require 'open-uri' -require 'tmpdir' - -VALID_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/README.md' -NON_EXESTENT_FILE_URI = 'https://github.com/shakacode/uber_task/raw/main/NON_EXISTENT.md' module Examples class DownloadFile - def self.run(to:, source: VALID_FILE_URI, **task_options) + def self.run(uri:, to:, **task_options) UberTask.run( 'Download file from external source', - default_retry_wait: 3, - retry_count: 5, - vital: false, + default_retry_wait: 5, + retry_count: 3, **task_options, ) do - UberTask.on_retry do + UberTask.on_success do UberTask.logger.info( - "Retrying to download file from #{source}...".yellow, + "Downloaded file #{uri} and saved it at #{to}".green, ) end - UberTask.on_success do + UberTask.on_retry do UberTask.logger.info( - "Downloaded file #{source} and saved it at #{to}".green, + "Retrying to download file from #{uri}...".yellow, ) end - save_external_file!(source: source, to: to) + save_external_file!(uri: uri, to: to) end end - def self.save_external_file!(source:, to:) - URI.parse(source).open { |io| File.write(to, io.read) } - rescue OpenURI::HTTPError => err - raise UberTask::RetryTask.new(reason: err.message) + def self.save_external_file!(uri:, to:) + URI.parse(uri).open { |io| File.write(to, io.read) } end private_class_method :save_external_file! end end - -if __FILE__ == $PROGRAM_NAME - Dir.mktmpdir do |dir| - filepath = File.join(dir, 'test') - - puts '--- Running successfull case ---' - Examples::DownloadFile.run(source: VALID_FILE_URI, to: filepath) - - puts "\n--- Running failing case with `vital: true`---\n" - begin - Examples::DownloadFile.run( - source: NON_EXESTENT_FILE_URI, - to: filepath, - vital: true, - ) - rescue StandardError - UberTask.logger.info 'Error was raised'.red - end - - puts "\n--- Running failing case with `vital: false`---\n" - Examples::DownloadFile.run( - source: NON_EXESTENT_FILE_URI, - to: filepath, - vital: false, - ) - UberTask.logger.info 'Error wasn\'t raised'.green - - puts "\n--- Running failing case with `retry_count: 1`---\n" - Examples::DownloadFile.run( - source: NON_EXESTENT_FILE_URI, - to: filepath, - retry_count: 1, - ) - - puts "\n--- Running failing case with `default_retry_wait: 0`---\n" - Examples::DownloadFile.run( - source: NON_EXESTENT_FILE_URI, - to: filepath, - default_retry_wait: 0, - ) - end -end diff --git a/examples/failing_task.rb b/examples/failing_task.rb new file mode 100644 index 0000000..b916c4b --- /dev/null +++ b/examples/failing_task.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'uber_task' + +module Examples + class FailingTask + Error = Class.new(StandardError) + + def self.run(**task_options) + UberTask.run('Failing task', **task_options) do + raise Error, 'failed' + end + end + end +end diff --git a/examples/move_file.rb b/examples/move_file.rb index f6dfb06..4954b83 100644 --- a/examples/move_file.rb +++ b/examples/move_file.rb @@ -2,17 +2,15 @@ require 'uber_task' require 'colorize' -require 'tmpdir' require 'fileutils' module Examples class MoveFile def self.run(from:, to:, **task_options) UberTask.run( - 'Download file from external source', + 'Move file', default_retry_wait: 1, retry_count: 3, - vital: false, **task_options, ) do UberTask.on_success do @@ -31,54 +29,7 @@ def self.run(from:, to:, **task_options) def self.move_file!(from:, to:) FileUtils.mv(from, to) - rescue Errno::ENOENT => err - raise UberTask::RetryTask.new(reason: err.message) end private_class_method :move_file! end end - -if __FILE__ == $PROGRAM_NAME - Dir.mktmpdir do |dir| - File.open(File.join(dir, 'old_path'), 'w') do |file| - file.write('test') - - puts '--- Running successfull case ---' - Examples::MoveFile.run(from: file.path, to: File.join(dir, 'new_path')) - end - - ### Notice that task has `vital: true` so error is raised - puts "\n--- Running failing case with `vital: true`---\n" - begin - Examples::MoveFile.run( - from: 'invalid_path', - to: File.join(dir, 'new_path'), - vital: true, - ) - rescue StandardError - UberTask.logger.info 'Error was raised'.red - end - - ### Notice that task has `vital: false` so error isn't raised - puts "\n--- Running failing case with `vital: false`---\n" - Examples::MoveFile.run( - from: 'invalid_path', - to: File.join(dir, 'new_path'), - vital: false, - ) - - puts "\n--- Running failing case with `retry_count: 1`---\n" - Examples::MoveFile.run( - from: 'invalid_path', - to: File.join(dir, 'new_path'), - retry_count: 1, - ) - - puts "\n--- Running failing case with `default_retry_wait: 3`---\n" - Examples::MoveFile.run( - from: 'invalid_path', - to: File.join(dir, 'new_path'), - default_retry_wait: 3, - ) - end -end