Sha256: e7bc936f1dfd4f0366b7cde85ebf04cfaad40b786fc16beb0caf6d6cd9c9c5bd

Contents?: true

Size: 2 KB

Versions: 17

Compression:

Stored size: 2 KB

Contents

# @title Extending Polyphony

# Extending Polyphony

Polyphony was designed to ease the transition from blocking APIs and
callback-based API to non-blocking, fiber-based ones. It is important to
understand that not all blocking calls can be easily converted into
non-blocking calls. That might be the case with Ruby gems based on C-extensions,
such as database libraries. In that case, Polyphony's built-in
[thread pool](#threadpool) might be used for offloading such blocking calls.

### Adapting callback-based APIs

Some of the most common patterns in Ruby APIs is the callback pattern, in which
the API takes a block as a callback to be called upon completion of a task. One
such example can be found in the excellent
[http_parser.rb](https://github.com/tmm1/http_parser.rb/) gem, which is used by
Polyphony itself to provide HTTP 1 functionality. The `HTTP:Parser` provides
multiple hooks, or callbacks, for being notified when an HTTP request is
complete. The typical callback-based setup is as follows:

```ruby
require 'http/parser'
@parser = Http::Parser.new

def on_receive(data)
  @parser < data
end

@parser.on_message_complete do |env|
  process_request(env)
end
```

A program using `http_parser.rb` in conjunction with Polyphony might do the
following:

```ruby
require 'http/parser'
require 'polyphony'

def handle_client(client)
  parser = Http::Parser.new
  req = nil
  parser.on_message_complete { |env| req = env }
  loop do
    parser << client.read
    if req
      handle_request(req)
      req = nil
    end
  end
end
```

Another possibility would be to monkey-patch `Http::Parser` in order to
encapsulate the state of the request:

```ruby
class Http::Parser
  def setup
    self.on_message_complete = proc { @request_complete = true }
  end

  def parser(data)
    self << data
    return nil unless @request_complete

    @request_complete = nil
    self
  end
end

def handle_client(client)
  parser = Http::Parser.new
  loop do
    if req == parser.parse(client.read)
      handle_request(req)
    end
  end
end
```

Version data entries

17 entries across 17 versions & 1 rubygems

Version Path
polyphony-1.6 docs/extending.md
polyphony-1.5 docs/extending.md
polyphony-1.4 docs/extending.md
polyphony-1.3 docs/extending.md
polyphony-1.2.1 docs/extending.md
polyphony-1.2 docs/extending.md
polyphony-1.1.1 docs/extending.md
polyphony-1.1 docs/extending.md
polyphony-1.0.2 docs/extending.md
polyphony-1.0.1 docs/extending.md
polyphony-1.0 docs/extending.md
polyphony-0.99.6 docs/extending.md
polyphony-0.99.5 docs/extending.md
polyphony-0.99.4 docs/extending.md
polyphony-0.99.3 docs/extending.md
polyphony-0.99.2 docs/extending.md
polyphony-0.99.1 docs/extending.md