GithubHelp home page GithubHelp logo

rewinfrey / actionlogic Goto Github PK

View Code? Open in Web Editor NEW
31.0 31.0 3.0 3.26 MB

A business logic abstraction gem that provides structure to the organization and composition of business logic (Ruby)

Home Page: http://rickwinfrey.com/ActionLogic/

Ruby 100.00%
abstraction business-logic ruby

actionlogic's People

Contributors

dependabot[bot] avatar rewinfrey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

actionlogic's Issues

Type validations should use the class constant

After exploring type annotations in Haskell and Elm, using the class constant feels more natural than using a symbol.

The proposal would be to instead use class constant (e.g. String rather than :string). This also makes it easier for those new to ActionLogic because the use of a class constant is more intuitive rather than a symbol representation (particularly for user defined classes).

Create an example Rails application

For the sake of providing clear, real world examples, create a Rails app that performs logic.

The logic can be shows in a traditional Rails way and in the ActionLogic way.

Update README to document new ActionLogic::Configuration

For now this only includes benchmarking configuration options:

  • benchmark
  • benchmark_log
  • benchmark_formatter

By default benchmark is false (this must be explicitly set to true to enable benchmarking functionality):

ActionLogic::ActionConfiguration.configure do |config|
  config.benchmark = true
end

By default benchmark_log uses stdout unless a Ruby IO object is specified (like a File):

ActionLogic::ActionConfiguration.configure do |config|
  config.benchmark = true
  config.benchmark_log = File.open("benchmark.log", "w")
end

By default benchmark_formatter uses the ActionLogic::ActionBenchmark::DefaultFormatter. Any custom formatters should subclass ActionLogic::ActionBenchmark::DefaultFormatter or verify that the custom formatter class implements the same interface.

class CustomFormatter < ActionLogic::ActionBenchmark::DefaultFormatter

  # Custom formatters require you to define three methods:
  # `task`, `use_case` and `coordinator`

  # Each of the format methods receives two inputs:
  #1. `benchmark_result` :  type is a Ruby stdlib Benchmark instance

  #2. `context_name` :  type is a Ruby String representing the class name of the execution
  # context (`ActionTask`, `ActionUseCase`, or `ActionCoordinator`  class)

  # A `benchmark_log` attr_reader is provided to write to within the `task`, `use_case` or 
  # `coordinator` methods.

  def task(benchmark_result, context_name)
    benchmark_log.puts("[task] #{context_name}: #{benchmark_result.real}")
  end

  def use_case(benchmark_result, context_name)
    benchmark_log.puts("[use case] #{context_name}: #{benchmark_result.real}")
  end

  def coordinator(benchmark_result, context_name)
    benchmark_log.puts("[coordinator] #{context_name}: #{benchmark_result.real}")
  end
end

# To use the CustomFormatter formatter class, we can configure ActionLogic like so:
ActionLogic::ActionConfiguration.configure do |config|
  config.benchmark = true
  config.benchmark_log = File.open("benchmark.log", "w")
  config.benchmark_formatter = CustomFormatter
end

# Using this configuration with the test suite yields a benchmark output formatted like so:

SimpleTestTask: 3.322999691590667e-05
SimpleTestUseCase: 0.00011545396409928799
UseCaseTestTask1: 2.9074028134346008e-05
UseCaseTestTask2: 2.7913018129765987e-05
SimpleTestUseCase2: 0.00011622201418504119
SimpleTestTask: 6.190297426655889e-05
SimpleTestUseCase: 0.00018308503786101937
...

# If no custom formatter is defined, ActionLogic provides a default formatter
# whose output is a machine readable format for easy parsing:

context:   SimpleTestTask                                     user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000048
context:   SimpleTestTask                                     user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000030
context:   FailureTestTask                                    user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000038
context:   ErrorHandlerTestTask                               user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000042
context:   ValidateAroundCustomTypeTestTask                   user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000044
context:   ValidateAroundTestTask                             user_time: 0.000000   system_time: 0.000000   total_time: 0.000000   real_time: 0.000164
...

`context` is missing information for ActionLogic errors

When an ActionLogic error is thrown, the intent is to communicate the context in which the error was thrown (i.e. the name of the specific class). Instead the context today reports a generic catchall Class:

ActionLogic::AttributeTypeError: context: Class message: Attribute: integer_test with value:  was expected to be of type Fixnum but is NilClass

The issue is not threading the executionContext from ActionCore through to the ActionValidation methods. If executionContext is passed as an argument, when we find an error within any of the ActionValidation methods we would have the originating class information for producing a better error message.

Allow for custom validations

Allow users to register custom validations as part of ActionConfiguration.

Validations would include the default validations plus any registered during configuration.

Custom validations would be required to implement a call method.

Add benchmarking

In a recently conversation on LightService, I suggested making benchmarking available via a configuration object that also would allow you to specify a log file for the benchmark results. The benchmarking would measure the execution time of any ActionCoordinator, ActionUseCase or ActionTask.

I think this would be a fun and potentially useful feature for those in the future that may use ActionLogic and want to understand the how their various execution contexts are running to isolate long-running tasks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.