Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jgaskins/pennant
Feature flags in Crystal applications with pluggable backends (in-memory and Redis currently supported)
https://github.com/jgaskins/pennant
crystal feature-flags feature-toggles
Last synced: 22 days ago
JSON representation
Feature flags in Crystal applications with pluggable backends (in-memory and Redis currently supported)
- Host: GitHub
- URL: https://github.com/jgaskins/pennant
- Owner: jgaskins
- License: mit
- Created: 2021-08-08T05:48:36.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-08-08T08:08:58.000Z (over 3 years ago)
- Last Synced: 2024-12-09T10:55:44.489Z (25 days ago)
- Topics: crystal, feature-flags, feature-toggles
- Language: Crystal
- Homepage:
- Size: 11.7 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Pennant
Feature flags for your application, with pluggable backends.
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
pennant:
github: jgaskins/pennant
```2. Run `shards install`
## Usage
Load and configure Pennant:
```crystal
require "pennant"
require "redis"redis = Redis::Client.new
Pennant.config do |c|
c.adapter = Pennant::RedisAdapter.new(redis)
end
```Now, anywhere in your application, you can simply call `Pennant.enabled?("my-feature")` to see if a particular feature flag is enabled.
To enable or disable a feature flag, you can simply call `Pennant.enable("my-feature")` or `Pennant.disable("my-feature")`, respectively. To run this in production, you can run the following command at a production Bash prompt (assuming your Pennant configuration exists in `./config/pennant.cr`):
```
crystal eval 'require "./config/pennant"; Pennant.enable "my-feature"'
```For example, if your Crystal application is running on Heroku, you can prefix the command with `heroku run ...`. If it's running on Kubernetes, you could prefix it with `kubectl exec -it $POD -- ...`.
### Enabling for a given actor
Pennant allows enabling a feature for specific actors, such as specific users, groups. Any object in your application can be used for this purpose as long as it includes the `Pennant::Actor` mixin, which requires defining the `pennant_id` method:
```crystal
struct User
include Pennant::Actorgetter id : UUID
def pennant_id : String
"User:#{id}"
end
end
```The format of `pennant_id` is up to you, as long as it uniquely identifies that person, group, or concept and resolves to the same value for it every time. For database-backed objects, this is often a class (or table) name and a primary key.
Once you have this in place, you can check whether a feature is enabled by passing `for: actor` to the `enable`, `disable`, and `enabled?` method:
```crystal
if Pennant.enabled?("my-feature", for: current_user)
# new hotness
else
# old and busted
end
```### Enabling for a percentage of requests
Sometimes you don't necessarily want to enable a feature for the same people, but instead for a percentage of your application's traffic. For this, you can pass `percentage_of_time: 0.1` to `enable`:
```crystal
Pennant.enable("my-feature", percentage_of_time: 0.05)
```All calls to `Pennant.enabled?("my-feature")` will now return `true` 5% of the time.
## Web UI
There is a web UI in progress to manage feature flags so that you don't need to enable/disable them via production shells. The intent is to be able to insert it into your `HTTP::Server` middleware:
```crystal
http = HTTP::Server.new([
HTTP::LogHandler.new,
Pennant::Web.new(mount_at: "/feature_flags"),
# the rest of your HTTP handler entries ...
])
```With the Lucky framework, you'd insert this into [your `middleware` array](https://luckyframework.org/guides/http-and-routing/http-handlers#built-in-handlers).
With this in place, if you visit your application at `/feature_flags` you will see a list of your feature flags and their current states.
## 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## Contributors
- [Jamie Gaskins](https://github.com/jgaskins) - creator and maintainer