README.md in isolator-0.0.1 vs README.md in isolator-0.1.0.pre

- old
+ new

@@ -25,26 +25,142 @@ end #=> raises Isolator::BackgroundJobError ``` +Of course, Isolator can detect _implicit_ transactions too. Consider this pretty common bad practice–enqueueing background job from `after_create` callback: + +```ruby +class Comment < ApplicationRecord + # the good way is to use after_create_commit + # (or not use callbacks at all) + after_create :notify_author + + private + + def notify_author + CommentMailer.comment_created(self).deliver_later + end +end + +Comment.create(text: "Mars is watching you!") +#=> raises Isolator::BackgroundJobError +``` + +Isolator is supposed to be used in tests and on staging. + ## Installation Add this line to your application's Gemfile: ```ruby +# We suppose that Isolator is used in development and test +# environments. group :development, :test do gem "isolator" end + +# Or you can add it to Gemfile with `require: false` +# and require it manually in your code. +# +# This approach is useful when you want to use it in staging env too. +gem "isolator", require: false ``` ## Usage -TBD +Isolator is a plug-n-play tool, so, it begins to work right after required. +However, there are some potential caveats: + +1) Isolator tries to detect the environment automatically and includes only necessary adapters. Thus the order of loading gems matters: make sure that `isolator` is required in the end (NOTE: in Rails, all adapters loaded after application initialization). + +2) Isolator does not distinguish framework-level adapters. For example, `:active_job` spy doesn't take into account which AJ adapter you use; if you are using a safe one (e.g. `Que`) just disable the `:active_job` adapter to avoid false negatives (i.e. `Isolator.adapters.active_job.disable!`). + +3) Isolator tries to detect the `test` environment and slightly change its behavior: first, it respect _transactional tests_; secondly, error raising is turned on by default (see [below](#configuration)). + +### Configuration + +```ruby +Isolator.configure do |config| + # Specify a custom logger to log offenses + config.logger = nil + + # Raise exception on offense + config.raise_exceptions = false # true in test env + + # Send notifications to uniform_notifier + config.send_notifications = false +end +``` + +Isolator relys on [uniform_notifier][] to send custom notifications. + +**NOTE:** `uniform_notifier` should be installed separately (i.e., added to Gemfile). + +### Supported ORMs + +- `ActiveRecord` >= 4.1 +- `ROM::SQL` (only if Active Support instrumentation extenstion is loaded) + +### Adapters + +Isolator has a bunch of built-in adapters: +- `:http` – built on top of [Sniffer][] +- `:active_job` +- `:sidekiq` + +You can dynamically enable/disable adapters, e.g.: + +```ruby +# Disable HTTP adapter == do not spy on HTTP requests +Isolator.adapters.http.disable! + +# Enable back + +Isolator.adapters.http.enable! +``` + +## Custom Adapters + +An adapter is just a combination of a _method wrapper_ and lifecycle hooks. + +Suppose that you have a class `Danger` with a method `#explode`, which is not safe to be run within a DB transaction. Then you can _isolate_ it (i.e., register with Isolator): + +```ruby +# The first argument is a unique adapter id, +# you can use it later to enable/disable the adapter +# +# The second argument is the method owner and +# the third one is a method name. +Isolotar.isolate :danger, Danger, :explode, **options + +# NOTE: if you want to isolate a class method, use signleton_class instead +Isolator.isolate :danger, Danger.singleton_class, :explode, **options +``` + +Possible `options` are: +- `exception_class` – an exception class to raise in case of offense +- `exception_message` – custom exception message (could be specified without a class) + +You can also add some callbacks to be run before and after the transaction: + +```ruby +Isolator.before_isolate do + # right after we enter the transaction +end + +Isolator.after_isolate do + # right after the transaction has been committed/rollbacked +end +``` + ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/isolator. ## License The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). + +[Sniffer]: https://github.com/aderyabin/sniffer +[uniform_notifier]: https://github.com/flyerhzm/uniform_notifier