Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit - Readme Driven Development
- Loading branch information
0 parents
commit 0a0ba6c
Showing
8 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
*.gem | ||
*.rbc | ||
.bundle | ||
.config | ||
.yardoc | ||
Gemfile.lock | ||
InstalledFiles | ||
_yardoc | ||
coverage | ||
doc/ | ||
lib/bundler/man | ||
pkg | ||
rdoc | ||
spec/reports | ||
test/tmp | ||
test/version_tmp | ||
tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
source 'https://rubygems.org' | ||
|
||
# Specify your gem's dependencies in bustle.gemspec | ||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
# Bustle | ||
|
||
Activities recording and retrieving using a simple Pub/Sub architecture. | ||
|
||
The typical use cases are: | ||
|
||
- Timeline (e.g. tracking activities such as posting and commenting for users) | ||
- Logging | ||
|
||
## Installation | ||
|
||
Add this line to your application's Gemfile: | ||
|
||
```ruby | ||
gem 'bustle' | ||
``` | ||
|
||
## Usage | ||
|
||
### Configuration | ||
|
||
First of all, you will need to configure Bustle. If you are using Rails, you can put the following code in an initializer (e.g. `config/initializers/bustle.rb`). | ||
|
||
```ruby | ||
Bustle.config do |c| | ||
# Specify an intepreter strategy for intepreting app data | ||
# i.e. what your application uses for persistence | ||
# Bustle ships with an ActiveRecord intepreter strategy | ||
c.intepreter = Bustle::Intepreter::ActiveRecord | ||
|
||
# Specify a storage strategy for storing activities | ||
# Bustle ships with an ActiveRecord storage strategy | ||
c.storage = Bustle::Storage::ActiveRecord | ||
end | ||
``` | ||
|
||
For ActiveRecord, you will need the following migration file: | ||
|
||
```ruby | ||
class CreateBustleTables < ActiveRecord::Migration | ||
def change | ||
create_table :bustle_activities do |t| | ||
t.string :reference_class | ||
t.integer :reference_id | ||
t.string :action | ||
t.integer :publisher_id, :null => false | ||
t.timestamps | ||
end | ||
|
||
create_table :bustle_publishers do |t| | ||
t.string :reference_class, :null => false | ||
t.integer :reference_id, :null => false | ||
t.timestamps | ||
end | ||
|
||
create_table :bustle_subscribers do |t| | ||
t.string :reference_class, :null => false | ||
t.integer :reference_id, :null => false | ||
t.timestamps | ||
end | ||
|
||
create_table :bustle_subscriptions do |t| | ||
t.integer :publisher_id, :null => false | ||
t.string :subscriber_id, :null => false | ||
t.timestamps | ||
end | ||
|
||
add_index :bustle_activities, :publisher_id | ||
add_index :bustle_publishers, [:reference_class, :reference_id], :unique => true | ||
add_index :bustle_subscribers, [:reference_class, :reference_id], :unique => true | ||
add_index :bustle_subscriptions, :publisher_id | ||
add_index :bustle_subscriptions, :subscriber_id | ||
add_index :bustle_subscriptions, [:publisher_id, :subscriber_id], :unique => true | ||
end | ||
end | ||
``` | ||
|
||
### Flow | ||
|
||
Upon subscribing: | ||
|
||
1. Subscriber registers itself if not already registered | ||
2. Publisher registers itself if not already registered | ||
3. A Subscription is created for Subscriber and Publisher | ||
|
||
When activities occur: | ||
|
||
1. Publisher registers itself if not already registered | ||
2. Publisher publishes activity | ||
|
||
### API | ||
|
||
#### Register a Subscriber | ||
|
||
```ruby | ||
Bustle::Subscribers.add subscriber | ||
|
||
# example | ||
user = User.find(1) | ||
Bustle::Subscribers.add user | ||
``` | ||
|
||
#### Register a Publisher | ||
|
||
```ruby | ||
Bustle::Publishers.add publisher | ||
|
||
# example | ||
post = Post.find(1) | ||
Bustle::Publishers.add post | ||
``` | ||
|
||
#### Create a Subscription | ||
|
||
```ruby | ||
Bustle::Subscriptions.add bustle_publisher, bustle_subscriber | ||
|
||
# example | ||
publisher = Bustle::Publishers.find(Post.first) | ||
subscriber = Bustle::Subscribers.find(User.first) | ||
Bustle::Subscriptions.add publisher, subscriber | ||
``` | ||
|
||
#### Find a Subscriber/Publisher/Subscription | ||
|
||
```ruby | ||
Bustle::Subscribers.find subscriber | ||
Bustle::Publishers.find publisher | ||
Bustle::Subscriptions.find bustle_publisher, bustle_subscriber # => Bustle::Subscription | ||
Bustle::Subscriptions.find bustle_publisher # => an array of Bustle::Subscription for the publisher | ||
Bustle::Subscriptions.find bustle_subscriber # => an array of Bustle::Subscription for the subscriber | ||
``` | ||
|
||
#### Remove a Subscriber/Publisher/Subscription | ||
|
||
```ruby | ||
Bustle::Subscribers.remove subscriber | ||
Bustle::Publishers.remove publisher | ||
Bustle::Subscriptions.remove bustle_publisher, bustle_subscriber | ||
``` | ||
|
||
Or: | ||
|
||
```ruby | ||
Bustle::Subscribers.find(subscriber).destroy | ||
Bustle::Publishers.find(publisher).destroy | ||
Bustle::Subscriptions.find(bustle_publisher, bustle_subscriber).destroy | ||
``` | ||
|
||
#### Publish an Activity | ||
|
||
```ruby | ||
Bustle::Activities.add bustle_publisher, action, activity | ||
# or | ||
Bustle::Publisher.publish action, activity | ||
|
||
# example | ||
post = Post.find(1) | ||
comment = post.comments.add(:content => "I'm a comment") | ||
Bustle::Publishers.add post | ||
publisher = Bustle::Publishers.find post | ||
publisher.publish 'new', comment | ||
``` | ||
|
||
#### Activities | ||
|
||
##### Retrieve Activities for a Subscriber | ||
|
||
```ruby | ||
Bustle::Activities.for bustle_subscriber | ||
# or | ||
Bustle::Subscriber.activities | ||
|
||
# example | ||
subscriber = Bustle::Subscribers.find(User.first) | ||
subscriber.activities | ||
``` | ||
|
||
##### Retrieve Activities by a Publisher | ||
|
||
```ruby | ||
Bustle::Activities.by bustle_publisher | ||
# or | ||
Bustle::Publisher.activities | ||
|
||
# example | ||
publisher = Bustle::Publishers.find(Post.first) | ||
publisher.activities | ||
``` | ||
|
||
##### Activities Filtering | ||
|
||
```ruby | ||
Bustle::Activities.for(bustle_subscriber).filter :key => :value | ||
# or | ||
Bustle::Subscriber.activities.filter :key => :value | ||
|
||
# example | ||
subscriber = Bustle::Subscribers.find(User.first) | ||
subscriber.activities.filter :action => 'new' | ||
subscriber.activities.by(publisher).filter(:action => 'new') | ||
``` | ||
|
||
Activities are normal enumerable objects from your chosen storage, so in ActiveRecord's case, you may use any Arel methods to query the result: | ||
|
||
```ruby | ||
subscriber.activities.filter(:action => 'new').order('created_at ASC').limit(10) | ||
``` | ||
|
||
## License | ||
|
||
This gem is released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). | ||
|
||
## Author | ||
|
||
[Fred Wu](https://github.com/fredwu), originally built for [500 Startups](http://500.co). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/env rake | ||
require "bundler/gem_tasks" | ||
require 'rake/testtask' | ||
|
||
Rake::TestTask.new do |t| | ||
t.libs.push 'lib' | ||
t.test_files = FileList['specs/**/*_spec.rb'] | ||
t.verbose = true | ||
end | ||
|
||
task :default => :test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# -*- encoding: utf-8 -*- | ||
require File.expand_path('../lib/bustle/version', __FILE__) | ||
|
||
Gem::Specification.new do |gem| | ||
gem.authors = ["Fred Wu"] | ||
gem.email = ["ifredwu@gmail.com"] | ||
gem.description = %q{Activities recording and retrieving using a simple Pub/Sub architecture.} | ||
gem.summary = gem.description | ||
gem.homepage = "https://github.com/fredwu/bustle" | ||
|
||
gem.files = `git ls-files`.split($\) | ||
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } | ||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) | ||
gem.name = "bustle" | ||
gem.require_paths = ["lib"] | ||
gem.version = Bustle::VERSION | ||
|
||
gem.add_development_dependency 'rake' | ||
gem.add_development_dependency 'simplecov' | ||
gem.add_development_dependency 'minitest-colorize' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require "bustle/version" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module Bustle | ||
VERSION = "0.0.1" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require 'simplecov' | ||
SimpleCov.start | ||
|
||
require 'minitest-colorize' | ||
require 'minitest/autorun' | ||
require 'minitest/spec' | ||
|
||
require File.expand_path('../../lib/bustle', __FILE__) |