GithubHelp home page GithubHelp logo

alephant-broker's Introduction

Alephant::Broker

Brokers requests for rendered templates, retrieved from S3 or a HTML endpoint.

Build StatusGem Version

Installation

Add this line to your application's Gemfile:

gem 'alephant-broker'

And then execute:

bundle install

Or install it yourself as:

gem install alephant-broker

Usage

The Broker is capable of retrieving rendered templates from either S3 or a HTML endpoint (e.g. alephant-publisher-request). This must be decided when creating an instance of the Broker, as a load strategy is given as a parameter (see below for examples).

Barebones

S3 Load Strategy
require 'alephant/broker'

config = {
  :s3_bucket_id      => 'test_bucket',
  :s3_object_path    => 'foo',
  :lookup_table_name => 'test_lookup'
}

request = {
  'PATH_INFO'      => '/component/foo',
  'QUERY_STRING'   => 'variant=bar',
  'REQUEST_METHOD' => 'GET'
}

Alephant::Broker::Application.new(
  Alephant::Broker::LoadStrategy::S3.new,
  config
).call(request).tap do |response|
  puts "status:  #{response.status}"
  puts "content: #{response.content}"
end
HTML Load Strategy
require 'alephant/broker'

class UrlGenerator < Alephant::Broker::LoadStrategy::HTTP::URL
  def generate(id, options)
    "http://example-api.com/data?id=#{id}"
  end
end

request = {
  'PATH_INFO'      => '/component/foo',
  'QUERY_STRING'   => 'variant=bar',
  'REQUEST_METHOD' => 'GET'
}

Alephant::Broker::Application.new(
  Alephant::Broker::LoadStrategy::HTTP.new(UrlGenerator.new),
  {}
).call(request).tap do |response|
  puts "status:  #{response.status}"
  puts "content: #{response.content}"
end

Note

The HTML load strategy relies upon being given a URLGenerator, which is used to generate the URL of the HTML endpoint (see below for example). The class must:

require 'alephant/broker'
require 'rack'

class UrlGenerator < Alephant::Broker::LoadStrategy::HTTP::URL
  def generate(id, options)
    "http://api.my-app.com/component/#{id}?#{to_query_string(options)}"
  end

  private

  def to_query_string(hash)
    Rack::Utils.build_query hash
  end
end
Revalidate Strategy
require 'alephant/broker'

config = {
  :s3_bucket_id                => 'test_bucket',
  :s3_object_path              => 'foo',
  :lookup_table_name           => 'test_lookup',
  :sqs_queue_name              => 'test_queue',
  :elasticache_config_endpoint => 'test_elisticache'
  :revalidate_cache_ttl        => 30
}

Alephant::Broker::Application.new(
  Alephant::Broker::LoadStrategy::Revalidate::Strategy.new,
  config
).call(request).tap do |response|
  puts "status:  #{response.status}"
  puts "content: #{response.content}"
end

The "Revalidate" strategy uses the following process flow:

https://github.com/BBC-News/Documentation/blob/master/Alephant/Diagrams/Alephant%20Revalidate%20Broker.png?raw=true

And uses the following AWS resources:

  • S3 - for storage of rendered components
  • DynamoDB - for recording S3 component locations
  • Elasticache - for caching S3 content and recording "inflight" messages
  • SQS - for communication between the broker and renderer

Rack App

Create config.ru using example below, and then run:

rackup config.ru
require 'alephant/broker'
require 'alephant/broker/load_strategy/http'

class UrlGenerator < Alephant::Broker::LoadStrategy::HTTP::URL
  def generate(id, options)
    "http://example-api.com/data?id=#{id}"
  end
end

run Alephant::Broker::Application.new(
  Alephant::Broker::LoadStrategy::HTTP.new(UrlGenerator.new),
  {}
)

Cache version number

The broker looks for a configuration value elasticache_cache_version and if it exists it uses it to construct the cache key. This allows the cache to be busted if the data in the cache changes, or for any other reason that it needs to be invalidated.

This version is added as a header to the response in the following format:

X-Cache-Version: {CACHE_VERSION}

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Create a new Pull Request.

Feel free to create a new issue if you find a bug.

alephant-broker's People

Contributors

alex-magana avatar darnould avatar dazoakley avatar ettomatic avatar fewstera avatar integralist avatar joearo avatar kenoir avatar kodikos avatar samfrench avatar stevenjack avatar woodyblah avatar zygotic99 avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 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  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  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

Forkers

akabiru

alephant-broker's Issues

Inconsistent batch request components

Problem

Scenario:

  • A batch request for 5 components.
  • 4 of the components are retrieved from the cache, however 1 component's cache has expired/not exist.
  • Broker requests content for the expired component, and updates the cache before returning it.

In this situation, one of the components may have more recent data which could contradict the other 4 components (e.g. stock price).

Solution

  • If 1+ of many components in a batch request is required to fetch new content, then all components must follow suit.
  • This can be given as an option with the JSON body of the batch POST request (defaults to false).

Implementation

  • Before the point where the components are loaded in parallel, the broker must evaluate if all requested components exist in the cache.
  • This boolean value is then handed to the LoadStrategy, which uses it to determine if it is necessary to check the cache.
  • Make sure that we aren't checking the cache twice.

Remove Multi

Multi is no longer used and has become stale after the changes seen in #14 - therefore meaning that it has become an overhead to support.

It can be removed within a PR (reverted in future if necessary).

Loading components in parallel (Request::Batch)

Problem

This functionality was removed within #14 as we were seeing errors, most likely due to race conditions. It may also be due to using Peach which is now quite an old gem.

Solution

Refactor Request::Batch so that the following method loads components in parallel.

def components_for(env)
  env.data['components'].map do |c|
    @component_factory.create(
      c['component'],
      batch_id,
      c['options']
    )
  end
end

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.