Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdanRada committed Feb 15, 2016
2 parents b6f5b8b + 3b7a102 commit 9184c73
Show file tree
Hide file tree
Showing 23 changed files with 1,236 additions and 586 deletions.
26 changes: 26 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
engines:
bundler-audit:
enabled: false
csslint:
enabled: false
eslint:
enabled: false
fixme:
enabled: true
rubocop:
enabled: true
ratings:
paths:
- Gemfile.lock
- "**.css"
- "**.js"
- "**.jsx"
- "**.rb"
exclude_paths:
- spec/**/*
- examples/**/*
- test/**/*
- vendor/**/*
- bin/**/*
- .codeclimate.yml
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ spec/dummy/log/*.log
spec/dummy/tmp/
coverage
tags
#Gemfile.lock
/nbproject/
/.git-rewrite/
.yardoc/
Expand Down
11 changes: 11 additions & 0 deletions .reek
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
Attribute:
enabled: false
TooManyInstanceVariables:
enabled: false
TooManyMethods:
enabled: false
UtilityFunction:
enabled: false
exclude_paths:
- examples
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ AllCops:
- vendor/**/**
- examples/**/**

ClassLength:
Max: 500

Documentation:
Enabled: true

Expand Down
16 changes: 0 additions & 16 deletions Guardfile

This file was deleted.

78 changes: 74 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
celluloid_pubsub
================

[![Gem Version](https://badge.fury.io/rb/celluloid_pubsub.svg)](http://badge.fury.io/rb/celluloid_pubsub) [![Build Status](https://travis-ci.org/bogdanRada/celluloid_pubsub.png?branch=master,develop)](https://travis-ci.org/bogdanRada/celluloid_pubsub) [![Coverage Status](https://coveralls.io/repos/bogdanRada/celluloid_pubsub/badge.svg?branch=master)](https://coveralls.io/r/bogdanRada/celluloid_pubsub?branch=master) [![Code Climate](https://codeclimate.com/github/bogdanRada/celluloid_pubsub/badges/gpa.svg)](https://codeclimate.com/github/bogdanRada/celluloid_pubsub) [![Repo Size](https://reposs.herokuapp.com/?path=bogdanRada/celluloid_pubsub)](https://github.com/bogdanRada/celluloid_pubsub) [![Gem Downloads](https://ruby-gem-downloads-badge.herokuapp.com/celluloid_pubsub?type=total&style=dynamic)](https://github.com/bogdanRada/celluloid_pubsub) [![Documentation Status](https://inch-ci.org/github/bogdanRada/celluloid_pubsub.svg?branch=master)](https://inch-ci.org/github/bogdanRada/celluloid_pubsubb) [![Maintenance Status](http://stillmaintained.com/bogdanRada/celluloid_pubsub.png)](https://github.com/bogdanRada/celluloid_pubsub)
[![Gem Version](https://badge.fury.io/rb/celluloid_pubsub.svg)](http://badge.fury.io/rb/celluloid_pubsub) [![Build Status](https://travis-ci.org/bogdanRada/celluloid_pubsub.png?branch=master,develop)](https://travis-ci.org/bogdanRada/celluloid_pubsub) [![Coverage Status](https://coveralls.io/repos/bogdanRada/celluloid_pubsub/badge.svg?branch=master)](https://coveralls.io/r/bogdanRada/celluloid_pubsub?branch=master) [![Code Climate](https://codeclimate.com/github/bogdanRada/celluloid_pubsub/badges/gpa.svg)](https://codeclimate.com/github/bogdanRada/celluloid_pubsub) [![Repo Size](https://reposs.herokuapp.com/?path=bogdanRada/celluloid_pubsub)](https://github.com/bogdanRada/celluloid_pubsub) [![Gem Downloads](https://ruby-gem-downloads-badge.herokuapp.com/celluloid_pubsub?type=total&style=dynamic)](https://github.com/bogdanRada/celluloid_pubsub) [![Documentation Status](https://inch-ci.org/github/bogdanRada/celluloid_pubsub.svg?branch=master)](https://inch-ci.org/github/bogdanRada/celluloid_pubsubb) [![Analytics](https://ga-beacon.appspot.com/UA-72570203-1/bogdanRada/celluloid_pubsub)](https://github.com/bogdanRada/celluloid_pubsub)

Description
-----------

CelluloidPubsub is a simple ruby implementation of publish subscribe design patterns using celluloid actors and websockets, using Celluloid::Reel server

Starting with version 0.4.0, Redis support was added [courtesy of em-hiredis](https://github.com/mloughran/em-hiredis)

Requirements
------------

1. [Ruby 1.9.x or Ruby 2.x.x](http://www.ruby-lang.org)
2. [Celluloid >= 0.16.0](https://github.com/celluloid/celluloid)
3. [Celluloid-IO >= 0.16.2](https://github.com/celluloid/celluloid-io)
4. [Reel >= 0.5.0](https://github.com/celluloid/reel)
5. [Celluloid-websocket-client = 0.0.1](https://github.com/jeremyd/celluloid-websocket-client)
6. [ActiveSuport >= 4.2.0](https://rubygems.org/gems/activesupport)
4. [Reel >= 0.6.0](https://github.com/celluloid/reel)
5. [http >= 1.0.2](https://github.com/httprb/http)
6. [Celluloid-websocket-client = 0.0.1](https://github.com/jeremyd/celluloid-websocket-client)
7. [ActiveSuport >= 4.2.0](https://rubygems.org/gems/activesupport)
8. [em-hiredis >= 0.3.0](https://github.com/mloughran/em-hiredis)
9. [json >= 1.8.3](https://github.com/flori/json)

Compatibility
-------------
Expand All @@ -38,6 +43,71 @@ Add the following to your Gemfile:

Please read [Release Details](https://github.com/bogdanRada/celluloid_pubsub/releases) if you are upgrading. We break backward compatibility between large ticks but you can expect it to be specified at release notes.

Usage
-----

Creating a websocket server is simple as doing this. This are all the options available with their default values.

```ruby
CelluloidPubsub::WebServer.supervise_as(:web_server,
enable_debug: true, # if debug messages should be logged
use_redis: false , # if set to true, will instantiate a RedisReactor class to handle each connection, which requires Redis to be available. Otherwise will use a simple Reactor to handle the connections which has no dependencies .
log_file_path: "path/to/log_file.log", # The log file where all debugging information will be printed
hostname: "0.0.0.0", # the hostname of the server.
port: 1234, # the port on which the server will listen for connections
path: '/ws', # the relative path used in the URL where connections are allowed to connect
spy: false, # whether to spy all internal Websocket connections in order to get more debugging information
backlog: 1024 # the number of connections allowed to be connected to the server at a certain time
)
```

Creating a client is simple as doing this. If you provide the channel when you initialize the **CelluloidPubsub::Client** it will automatically start the subscription to that channel. But sometimes, you might want to subscribe at a later time, so you can just omit the channel when you initialize the client, and use instead **@client.subscribe('test_channel')**. After the subscription has started, the client must implement the method **on_message** and the **on_close** method (called when client disconnects from the channel). The method **on_message** will receive all incoming messages from the server. You can test if the subscription was successful by doing this **@client.succesfull_subscription?(message)**.

```ruby
class MyAwesomeClient
include Celluloid
include Celluloid::Logger

def initialize(options = {})
@client = CelluloidPubsub::Client.new({
actor: Actor.current,
channel: 'test_channel', # the channel to which this client will subscribe to.
log_file_path: "path/to/log_file.log", # The log file where all debugging information will be printed
hostname: "0.0.0.0", # the hostname of the server.
port: 1234,# the port on which the connection will be made to
path: '/ws', # the relative path used in the URL where the connection will be connecting to
enable_debug: false # if debug messages should be logged
}.merge(options))
end

def on_message(message)
if @client.succesfull_subscription?(message)
puts "subscriber got successful subscription #{message.inspect}"
@client.publish('test_channel2', 'data' => ' subscriber got successfull subscription') # the message needs to be a Hash
else
puts "subscriber got message #{message.inspect}"
end
end

def on_close(code, reason)
puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
terminate
end


end

```

The methods available that the **CelluloidPubsub::Client** instance can execute are:

- subscribe -- subscribe - accepts a string as a channel name
- publish - accepts a string as a channel name, and a Hash object
- unsubscribe - accepts a string as a channel_name from which the client will unsubscribe from
- unsubscribe_clients - accepts a string as a channel_name . This will disconnect all clients that are subscribed to that channel.
- unsubscribe_all - This does not have any parameters. Will unsubscribe all clients from all channnels
- on_close - This accepts a code and a reason as parameters. This method will be called when the client disconnects from the channel.

Examples
--------

Expand Down
27 changes: 3 additions & 24 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,12 @@ require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'coveralls/rake/task'
require 'yard'
require 'yard-rspec'
Coveralls::RakeTask.new

RSpec::Core::RakeTask.new(:spec) do |spec|
spec.rspec_opts = ['--backtrace', '--fail-fast'] if ENV['DEBUG']
end

# desc "Prepare dummy application"
# task :prepare do
# ENV["RAILS_ENV"] ||= 'test'
# require File.expand_path("./spec/dummy/config/environment", File.dirname(__FILE__))
# Dummy::Application.load_tasks
# Rake::Task["db:test:prepare"].invoke
# end
YARD::Config.options[:load_plugins] = true
YARD::Config.load_plugins

Expand All @@ -26,31 +18,18 @@ YARD::Rake::YardocTask.new do |t|
t.stats_options = ['--list-undoc'] # optional
end

unless ENV['TRAVIS']
require 'rvm-tester'
RVM::Tester::TesterTask.new(:suite) do |t|
t.rubies = %w(1.9.3 2.0.0 2.1.0) # which versions to test (required!)
t.bundle_install = true # updates Gemfile.lock, default is true
t.use_travis = true # looks for Rubies in .travis.yml (on by default)
t.command = 'bundle exec rake' # runs plain "rake" by default
t.env = { 'VERBOSE' => '1', 'RAILS_ENV' => 'test', 'RACK_ENV' => 'test' } # set any ENV vars
t.num_workers = 5 # defaults to 3
t.verbose = true # shows more output, off by default
end
end

desc 'Default: run the unit tests.'
task default: [:all]

desc 'Test the plugin under all supported Rails versions.'
task :all do |_t|
if ENV['TRAVIS']
exec(' bundle exec phare && bundle exec rake spec && bundle exec rake coveralls:push')
exec('bundle exec rake spec && bundle exec rake coveralls:push')
else
exec('bundle exec rubocop -a . && bundle exec phare && bundle exec rake spec')
exec('bundle exec rake spec')
end
end

task :docs do
exec(' bundle exec rubocop -a . && bundle exec phare && bundle exec inch --pedantic && bundle exec yard')
exec('bundle exec inch --pedantic && bundle exec yard --list-undoc')
end
24 changes: 9 additions & 15 deletions celluloid_pubsub.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,23 @@ Gem::Specification.new do |s|
s.test_files = s.files.grep(/^(spec)/)
s.require_paths = ['lib']

s.add_runtime_dependency 'celluloid', '>= 0.16', '>= 0.16.0'
s.add_runtime_dependency 'celluloid', '>= 0.16', '>= 0.16.0' # TODO: upgrade to version 0.17 - work in progress
s.add_runtime_dependency 'celluloid-io', '>= 0.16', '>= 0.16.2'
s.add_runtime_dependency 'reel', '>= 0.5', '>= 0.5.0'
s.add_runtime_dependency 'http', '~> 0.9.8', '>= 0.9.8' # TODO: remove this once fixed in reel gem
s.add_runtime_dependency 'celluloid-websocket-client', '0.0.1'
s.add_runtime_dependency 'activesupport', '>= 4.1', '>= 4.1.0'
s.add_runtime_dependency 'versionomy', '>= 0.4', '>= 0.4.4'
s.add_runtime_dependency 'reel', '~> 0.6', '>= 0.6.0'
s.add_runtime_dependency 'http', '~> 1.0', '>= 1.0.2'
s.add_runtime_dependency 'celluloid-websocket-client', '~> 0.0', '>= 0.0.1'
s.add_runtime_dependency 'activesupport', '~> 4.1', '>= 4.1.0'
s.add_runtime_dependency 'em-hiredis', '~> 0.3', '>= 0.3.0'
s.add_runtime_dependency 'json', '~> 1.8', '>= 1.8.3'

s.add_development_dependency 'rspec-rails', '~> 3.3', '>= 3.3'
s.add_development_dependency 'guard', '~> 2.13', '>= 2.13'
s.add_development_dependency 'guard-rspec', '~> 4.6', '>= 4.6'
s.add_development_dependency 'rspec', '~> 3.4', '>= 3.4'
s.add_development_dependency 'simplecov', '~> 0.10', '>= 0.10'
s.add_development_dependency 'simplecov-summary', '~> 0.0.4', '>= 0.0.4'
s.add_development_dependency 'mocha', '~> 1.1', '>= 1.1'
s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7'
s.add_development_dependency 'rvm-tester', '~> 1.1', '>= 1.1'

s.add_development_dependency 'rubocop', '~> 0.33', '>= 0.33'
s.add_development_dependency 'phare', '~> 0.7', '>= 0.7'
s.add_development_dependency 'rake', '~> 10.5', '>= 10.5'
s.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7'
s.add_development_dependency 'yard-rspec', '~> 0.1', '>= 0.1'
s.add_development_dependency 'redcarpet', '~> 3.3', '>= 3.3'
s.add_development_dependency 'github-markup', '~> 1.3', '>= 1.3.3'
s.add_development_dependency 'inch', '~> 0.6', '>= 0.6'
s.add_development_dependency 'guard-inch', '~> 0.1', '>= 0.1.0'
end
2 changes: 2 additions & 0 deletions examples/redis_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ENV['USE_REDIS'] = 'true'
require_relative './shared_classes'
72 changes: 72 additions & 0 deletions examples/shared_classes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'bundler/setup'
require 'celluloid_pubsub'
require 'logger'

debug_enabled = ENV['DEBUG'].present? && ENV['DEBUG'].to_s == 'true'
use_redis = ENV['USE_REDIS'].present? && ENV['USE_REDIS'].to_s == 'true'
log_file_path = File.join(File.expand_path(File.dirname(__FILE__)), 'log', 'celluloid_pubsub.log')

# actor that subscribes to a channel
class Subscriber
include CelluloidPubsub::BaseActor

def initialize(options = {})
@client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel' }.merge(options))
end

def on_message(message)
if @client.succesfull_subscription?(message)
puts "subscriber got successful subscription #{message.inspect}"
@client.publish('test_channel2', 'data' => ' subscriber got successfull subscription') # the message needs to be a Hash
else
puts "subscriber got message #{message.inspect}"
end
end

def on_close(code, reason)
puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
terminate
end


end

# actor that publishes a message in a channel
class Publisher
include CelluloidPubsub::BaseActor

def initialize(options = {})
@client = CelluloidPubsub::Client.new({ actor: Actor.current, channel: 'test_channel2' }.merge(options))
end

def on_message(message)
if @client.succesfull_subscription?(message)
puts "publisher got successful subscription #{message.inspect}"
@client.publish('test_channel', 'data' => ' my_message') # the message needs to be a Hash
else
puts "publisher got message #{message.inspect}"
end
end

def on_close(code, reason)
puts "websocket connection closed: #{code.inspect}, #{reason.inspect}"
terminate
end

end


CelluloidPubsub::BaseActor.setup_actor_supervision(CelluloidPubsub::WebServer, actor_name: :web_server, args: {enable_debug: debug_enabled, use_redis: use_redis,log_file_path: log_file_path })
CelluloidPubsub::BaseActor.setup_actor_supervision(Subscriber, actor_name: :subscriber, args: {enable_debug: debug_enabled })
CelluloidPubsub::BaseActor.setup_actor_supervision(Publisher, actor_name: :publisher, args: {enable_debug: debug_enabled })


signal_received = false

Signal.trap('INT') do
puts "\nAn interrupt signal has been triggered!"
signal_received = true
end

sleep 0.1 until signal_received
puts 'Exited succesfully! =)'
Loading

0 comments on commit 9184c73

Please sign in to comment.