Skip to content

Support observers #478

Closed
Closed

Description

@ixti

In #476 I proposed to warn in some edge cases. Truth is - I hate when libraries are polluting STDERR/STDOUT without the way to control their verbosity level. So my first idea was - let's provide logging API, but in fact logger is simply a very specific use case of observer:

class MyHttpLogger < HTTP::Observer
  def initialize(logger)
    @logger = logger
  end

  def request_sent(request:)
    @logger.debug("#{request.verb} #{request.uri}")
  end
end

HTTP.observe(MyHttpLogger.new(Rails.logger)).get(url)

One thing that really bothers me in most Russian doll middleware architecture is pointless overhead of Array#each. With single observer object it will be possible to simply call:

observer&.request_sent(:request => request)

Providing HTTP::Observer base class will allow third parties to inject needed functionality on it using plain old Ruby:

HTTP::Observer.extend HotPotatoExtensions

Activity

  1. tarcieri commented on May 28, 2018

    @tarcieri
    Member

    There's been a ton of discussion about this (and even some merged code). You even have an issue open for it already I think: #209

    See also #177 and #240, as well as #346.

    I think some sort of hook system is great and needed for things like caching (#223).

    It'd also have the potential to simplify the webmock binding (#212).

    And yes, logging for debugging purposes would be great (#238, #348, #437). I'd really love something like what I implemented for Reel: https://github.com/celluloid/reel/wiki/Spy

    I am definitely a fan of avoiding the "middleware" pattern, especially as it pollutes the stack and makes backtraces that much more annoying to read (not to mention the performance implications).

    One thing I'd suggest is avoiding the "null object pattern" for this (i.e. defining a class of observers that does nothing), in lieu of gating the invocations on a branch. Ruby method dispatch is rather slow, and the null object pattern would greatly increase the number of method invocations this library performs.

  2. ixti commented on May 28, 2018

    @ixti
    MemberAuthor

    I feel myself so dumb now. Indeed we already had this conversation before! o_O Well the idea I had is pretty same to Spy in fact. with exception that there's a default implementation of observer and one will be able to just implement only needed handler to avoid if x.respond_to? guards which will impact performance. But in general API should accept an object that simply responds to all needed methods. Pretty much as Spy in fact. Just with ability to pass in any Spy-compliant implementation :D

  3. ixti commented on May 28, 2018

    @ixti
    MemberAuthor

    Duplicate of my own issue indeed. :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions