Code Monkey home page Code Monkey logo

featurehub-ruby-sdk's Introduction

Official FeatureHub Ruby SDK.

Overview

To control the feature flags from the FeatureHub Admin console, either use our demo version for evaluation or install the app using our guide here

SDK installation

Add the featurehub sdk gem to your Gemfile and/or gemspec if you are creating a library:

gem `featurehub-sdk`

To use it in your code, use:

require 'featurehub-sdk'

Options to get feature updates

There are 2 ways to request for feature updates via this SDK:

  • SSE (Server Sent Events) realtime updates mechanism

    In this mode, you will make a connection to the FeatureHub Edge server using using Server Sent Events, any updates to any features will come through in near realtime, automatically updating the feature values in the repository. This method is recommended for server applications.

  • FeatureHub polling client (GET request updates)

    In this mode you can set an interval (from 0 - just once) to any number of seconds between polling. This is more useful for when you have short term single threaded processes like command line tools. Batch tools that iterate over data sets and wish to control when updates happen can also benefit from this method.

This SDK uses concurrent ruby to ensure whichever option you choose stays open and continually updates your data.

Example

Check our example Sinatra app here

Quick start

Connecting to FeatureHub

There are 3 steps to connecting:

  1. Copy FeatureHub API Key from the FeatureHub Admin Console
  2. Create FeatureHub config
  3. Check FeatureHub Repository readiness and request feature state

1. API Key from the FeatureHub Admin Console

Find and copy your API Key from the FeatureHub Admin Console on the API Keys page - you will use this in your code to configure feature updates for your environments. It should look similar to this: default/71ed3c04-122b-4312-9ea8-06b2b8d6ceac/fsTmCrcZZoGyl56kPHxfKAkbHrJ7xZMKO3dlBiab5IqUXjgKvqpjxYdI8zdXiJqYCpv92Jrki0jY5taE. There are two options - a Server Evaluated API Key and a Client Evaluated API Key. More on this here

Client Side evaluation is intended for use in secure environments (such as microservices) and is intended for rapid client side evaluation, per request for example.

Server Side evaluation is more suitable when you are using an insecure client. (e.g. command line tool). This also means you evaluate one user per client.

2. Create FeatureHub config:

Create FeatureHubConfig. You need to provide the API Key and the URL of the FeatureHub Edge server.

config = FeatureHub::Sdk::FeatureHubConfig.new(ENV.fetch("FEATUREHUB_EDGE_URL"),
                                                 [ENV.fetch("FEATUREHUB_CLIENT_API_KEY")])
config.init

Note, you only ever need to do this once, a Config consists of a Repository (which holds state) and an Edge Server (which gets the updates and passes them on to the Repository). You can have many of them if you wish, but you don't need to.

to in Rails, you might create an initializer that does this:

Rails.configuration.fh_client = FeatureHub::Sdk::FeatureHubConfig.new(ENV.fetch("FEATUREHUB_EDGE_URL"),
                                                 [ENV.fetch("FEATUREHUB_CLIENT_API_KEY")]).init

in Sinatra (our example), it might do this:

class App < Sinatra::Base
    configure do
        set :fh_config, FeatureHub::Sdk::FeatureHubConfig.new(ENV.fetch("FEATUREHUB_EDGE_URL"),
                                                              [ENV.fetch("FEATUREHUB_CLIENT_API_KEY")])
    end
end

By default, this SDK will use SSE client. If you decide to use FeatureHub polling client, after initialising the config, you can add this:

config.use_polling_edge_service(30)
# OR
config.use_polling_edge_service # uses environment variable FEATUREHUB_POLL_INTERVAL or default of 30 

in this case it is configured for requesting an update every 30 seconds.

3. Check FeatureHub Repository readiness and request feature state

Check for FeatureHub Repository readiness:

if config.repository.ready?
  # do something
end

If you are not intending to use rollout strategies, you can pass empty context to the SDK:

def name_arg(name)
    if config.new_context.build.feature("FEATURE_TITLE_TO_UPPERCASE").flag
        "HELLO WORLD"
    else
        "hello world"
    end
end

If you are using rollout strategies and targeting rules they are all determined by the active user context. In this example we pass user_key to the context :

def name_arg(name)
    if config.new_context.user_key(name).build.feature("FEATURE_TITLE_TO_UPPERCASE").flag
        "HELLO WORLD"
    else
        "hello world"
    end
end

Well known fields have their own methods, or you can add custom values for fields using attribute_value(key, [values]). For example if you wish to trigger on specific contract ids and each user could have a different set of contract ids, you can add those attribute_value("contract_values", [2,17,45]) and have configured your strategy with a list of contract values which trigger the feature.

See more options to request feature states here

Using inside popular web servers

Because most of the popular webservers use a process per request distributed request distribution model, they will generally fork the process when they need more processes to handle the incoming traffic, and this will naturally kill the connection to FeatureHub. It does not however reset the cached repository. To ensure your fork is back up in running, for various frameworks you will need to ensure the Edge connection is restarted. This consists of

config.force_new_edge_service

Resetting in Passenger

In your config.ru

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      # e.g.
      # App.settings.fh_config.force_new_edge_service
    end
  end
end

Resetting in Puma

on_worker_boot do
      # e.g.
      # App.settings.fh_config.force_new_edge_service
end

Resetting in Unicorn

after_fork do |_server, _worker|
      # e.g.
      # App.settings.fh_config.force_new_edge_service
end

Resetting in Spring

Spring.after_fork do 
      # e.g.
      # App.settings.fh_config.force_new_edge_service
end

Extracting the state

You can extract the state from a repository and store it somewhere and reload it, but it should be done so using the JSON mechanism so it parses correctly.

require 'json'

state = config.repository.extract_feature_state

# somehow save it
save(state.to_json)

# some later stage, reload it or use it as a cache
config.repository.notify(:features, JSON.parse(read_state))

Readyness

It is encourage that you include the ready state of the repository in your readyness check. If your server cannot connect to your FeatureHub repository and cannot sensibly operate without it, it is not ready. Once it has received initial state it will remain ready even when it temporarily loses connections.

It is only if the key is invalid, or if the repository has never received state, that the repository is marked not ready. To determine readyness:

config.repository.ready?

featurehub-ruby-sdk's People

Contributors

cspalding avatar dependabot[bot] avatar irinasouth avatar kasperite avatar rvowles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

featurehub-ruby-sdk's Issues

Feature Request - Omitting Feature Hub API Key Logging

Is your feature request related to a problem? Please describe.
As a Feature Hub consumer, from a (security standpoint) seeing the API key consistently logged raises security concerns.

Describe the solution you'd like
It would be nice to be able to disable API key logging either via an environment variable or flag in the Feature Hub UI.

Describe alternatives you've considered
Creating a custom logging wrapper that extrapolates relevant information and removes the API key from all transmitted logs.

Additional context
Add any other context or screenshots about the feature request here.

Questions around contributing & docs

Hey there! This SDK is awesome. My team is looking into using Featurehub within a Rails application, and using this SDK appears to be preferable to us compared to building a client from the OpenAPI Spec (which is also great to have). I do have a couple of questions about the project and I'm hoping this is the correct place to ask. If not, feel free to close the issue and, if you have time, point me in the right direction.

I see that this is a very fresh repo (first commit was around 18 days ago at the time of this writing). It appears that it went through a few days of rapid development but has slowed down a bit. Are y'all still working on updating the SDK at all, or is development complete for the foreseeable future?

If there is any ongoing development, do you have any public documentation around what features are still being added or changed? Similarly, I assume since this is open-source y'all would accept PR's from outside of the featurehub organization (within reason), but I wanted to verify that assumption.

Thanks in advance for any info you can provide! And thanks again for developing this SDK, it's really great.

Analytics Support

I know we chatted about this briefly in a previous issue, but I wanted to get it documented on its own. This client currently doesn't support the GA integration that other FeatureHub SDKs do support. Is there an outline for how to add GA support to this SDK? Is it on the roadmap to add GA support to this SDK?

Thanks for any information!

Syncing feature state upstream

Hi @rvowles ๐Ÿ‘‹

Existing README is sparse so I guess I will double check here. How do you update feature flag using this SDK? I can update feature state using FeatureHubRepository#notify but can't see how the state is synced upstream to FeatureHub.

Am I right to think that current SDK doesn't have this ability?

Thanks

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.