From 415261748d3dcf10678b96c1e81689d2f9f0274f Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Fri, 20 Apr 2018 10:52:41 +0800 Subject: [PATCH 1/9] require 'securerandom' Fixes errors with missing SecureRandom --- lib/message_bus/client.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/message_bus/client.rb b/lib/message_bus/client.rb index 5bb8184..709e5a1 100644 --- a/lib/message_bus/client.rb +++ b/lib/message_bus/client.rb @@ -1,5 +1,6 @@ require 'excon' require 'json' +require "securerandom" require 'message_bus/client/version' require 'message_bus/client/configuration' From 428cd418135d3c3530edd5063d834daedb13b454 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Mon, 9 Jul 2018 20:27:49 +0800 Subject: [PATCH 2/9] Remove coverage check Let's not check coverage yet while we make a fork of message_bus-client --- spec/coverage_helper.rb | 65 ----------------------------------------- spec/spec_helper.rb | 1 - 2 files changed, 66 deletions(-) delete mode 100644 spec/coverage_helper.rb diff --git a/spec/coverage_helper.rb b/spec/coverage_helper.rb deleted file mode 100644 index 27fee81..0000000 --- a/spec/coverage_helper.rb +++ /dev/null @@ -1,65 +0,0 @@ -# Simultaneous code coverage reporting to Coveralls and Code Climate. -# Latest version can be found at https://gist.github.com/lowjoel/6c2f2d3a08bb3786994f -require 'simplecov' - -module CoverageHelper - class << self - # Helper to include Coveralls/Code Climate coverage, but not require developers to install the - # gem. - # - # @param [String] name The name of the module to require. - # @param [Proc] initializer The block to execute when the module is required successfully. - def load(name, &initializer) - old_formatter = SimpleCov.formatter - require name - initializer.call - - merge_formatters(old_formatter, SimpleCov.formatter) - rescue LoadError => e - if e.path == name - puts format('Cannot find \'%s\', ignoring', name) if ENV['CI'] - else - raise e - end - end - - private - - # Merge two SimpleCov formatters into a single MultiFormatter. - # - # This method is idempotent if the old and new formatters are the same. - def merge_formatters(old_formatter, new_formatter) - return if old_formatter == new_formatter - - old_formatter = [*expand_formatter(old_formatter)] - new_formatter = [*expand_formatter(new_formatter)] - formatters = old_formatter + new_formatter - - SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatters) - end - - # Extracts the formatters from a MultiFormatter so we do not nest them. - def expand_formatter(formatter) - return formatter unless formatter.is_a?(SimpleCov::Formatter::MultiFormatter) - formatter.formatters - end - end -end - -if ENV['CI'] - # Coveralls - CoverageHelper.load('coveralls') do - Coveralls.wear!('rails') - end - - # Code Climate - CoverageHelper.load('codeclimate-test-reporter') do - CodeClimate::TestReporter.start - end - - # Code coverage exclusions - SimpleCov.start do - # SimpleCov configuration - # add_filter '/lib/extensions/active_record/connection_adapters/table_definition.rb' - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 81db7d9..951eb12 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,4 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) -require 'coverage_helper' require 'message_bus/client' # This file was generated by the `rspec --init` command. Conventionally, all From 878b9c37a7c13e94d79e8ab8b24110b4b0549388 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Mon, 9 Jul 2018 20:28:15 +0800 Subject: [PATCH 3/9] Ignore `spec/examples.txt` -- it's a file generated when specs are run --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0cb6eeb..b827cff 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ /doc/ /pkg/ /spec/reports/ +/spec/examples.txt /tmp/ From 7f3fd8b5b366c0d7df84eeef0cbb3bb67df9410f Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Mon, 9 Jul 2018 20:36:01 +0800 Subject: [PATCH 4/9] Run tests against Ruby 2.4.1 and 2.5.0 --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb45ab6..bdf3580 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: ruby rvm: - - 2.1.9 - - 2.2.5 - - 2.3.1 + - 2.4.1 + - 2.5.0 before_install: gem update bundler From a0d34bf50970559dea1128cae8c57ae923e0cfc8 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Mon, 9 Jul 2018 20:37:12 +0800 Subject: [PATCH 5/9] Default dev Ruby to 2.5.0 --- .ruby-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..437459c --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.5.0 From b4eace223f090eabf4f1b8fbab56b30264037db8 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Sun, 22 Apr 2018 10:53:33 +0800 Subject: [PATCH 6/9] Fix teardown of puma server The problem of the puma process living beyond the command that started it is confirmed on MacOS. This code may break things on Windows. --- Rakefile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 7c6aacf..bde1bec 100644 --- a/Rakefile +++ b/Rakefile @@ -11,9 +11,18 @@ task :server do end at_exit do - $stderr.puts "Killing pid #{pid}" - Process.kill('KILL', pid) - Process.wait(pid) + if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ + $stderr.puts "Killing pid #{pid}" + Process.kill('KILL', pid) + Process.wait(pid) + else + child_pid = `pgrep -P #{pid}`.to_i + pids = [child_pid, pid] + pids.each do |pid| + $stderr.puts "Killing pid #{pid}" + Process.kill('KILL', pid) + end + end end sleep 3 From b3a402ac0409b09e20c6cd878b7465736b8192b3 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Sun, 22 Apr 2018 11:56:07 +0800 Subject: [PATCH 7/9] Provide a way to customize the last_id of a channel This is not tested. There doesn't seem to be a way to test this without being able to reset the channel messages --- CHANGELOG.md | 9 +++++++++ lib/message_bus/client/message_handler.rb | 14 ++++++++------ spec/message_bus/client_spec.rb | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..35d567d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] +### Added +- Ability to specify `last_id` of a channel diff --git a/lib/message_bus/client/message_handler.rb b/lib/message_bus/client/message_handler.rb index 71bb0bc..13b8cba 100644 --- a/lib/message_bus/client/message_handler.rb +++ b/lib/message_bus/client/message_handler.rb @@ -1,6 +1,6 @@ module MessageBus::Client::MessageHandler SubscribedChannel = Struct.new(:callbacks, :last_id) do - def initialize(last_id = -1) + def initialize(last_id) self.callbacks = [] self.last_id = last_id end @@ -20,14 +20,16 @@ def initialize(base_url) @pending_messages = [] @subscribed_channels = {} - @subscribed_channels.default_proc = proc do |hash, key| - hash[key] = SubscribedChannel.new - end @payload = String.new end - def subscribe(channel, &callback) - @subscribed_channels[channel].callbacks << callback + def subscribe(channel, last_id=-1, &callback) + subscribed_channel = @subscribed_channels[channel] + if subscribed_channel.nil? + subscribed_channel = @subscribed_channels[channel] = + SubscribedChannel.new(last_id) + end + subscribed_channel.callbacks << callback end def unsubscribe diff --git a/spec/message_bus/client_spec.rb b/spec/message_bus/client_spec.rb index 26511de..c30a97a 100644 --- a/spec/message_bus/client_spec.rb +++ b/spec/message_bus/client_spec.rb @@ -37,7 +37,7 @@ def write_message(message, user = 'message_bus-client') end end - it 'receives messages' do + it 'receives new messages by default (last_id of -1)' do subject.start text = "Hello World! #{Random.rand}" @@ -72,7 +72,7 @@ def write_message(message, user = 'message_bus-client') subject.stop end - it 'receives messages' do + it 'receives new messages by default (last_id of -1)' do subject.start text = "Hello World! #{Random.rand}" From 581581708d307d6ca45d56f8d98b8abd203a4234 Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Mon, 9 Jul 2018 22:17:25 +0800 Subject: [PATCH 8/9] Add pry-byebug for development --- Gemfile | 2 ++ spec/spec_helper.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index a7f86bd..a550366 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,5 @@ source 'https://rubygems.org' # Specify your gem's dependencies in message_bus-client.gemspec gemspec + +gem "pry-byebug" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 951eb12..febe631 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'message_bus/client' +require "pry-byebug" # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. From 9204dd4dcde69bc331180519b0f7c751298f504d Mon Sep 17 00:00:00 2001 From: Ramon Tayag Date: Wed, 25 Apr 2018 08:33:25 +0800 Subject: [PATCH 9/9] Add ability to access `message_id` if specified in the callback --- CHANGELOG.md | 1 + README.md | 2 +- lib/message_bus/client/message_handler.rb | 9 +++++---- spec/message_bus/client_spec.rb | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35d567d..9ba175e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added - Ability to specify `last_id` of a channel +- Get access to `message_id` if specified in the callback diff --git a/README.md b/README.md index 02f36d3..58be5de 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The API is mostly equivalent with the JavaScript client: ```ruby client = MessageBus::Client.new('http://chat.samsaffron.com/') -client.subscribe('/message') do |payload| +client.subscribe('/message') do |payload, message_id| # Do stuff end diff --git a/lib/message_bus/client/message_handler.rb b/lib/message_bus/client/message_handler.rb index 13b8cba..08d6fc1 100644 --- a/lib/message_bus/client/message_handler.rb +++ b/lib/message_bus/client/message_handler.rb @@ -5,9 +5,9 @@ def initialize(last_id) self.last_id = last_id end - def callback(payload) + def callback(payload, message_id) callbacks.each do |callback| - callback.call(payload) + callback.call(payload, message_id) end end end @@ -82,8 +82,9 @@ def handle_message(message) subscription = @subscribed_channels[message['channel']] return unless subscription - subscription.last_id = message['message_id'] - subscription.callback(message['data']) + message_id = message['message_id'] + subscription.last_id = message_id + subscription.callback(message['data'], message_id) end def handle_status_message(message) diff --git a/spec/message_bus/client_spec.rb b/spec/message_bus/client_spec.rb index c30a97a..809a5dd 100644 --- a/spec/message_bus/client_spec.rb +++ b/spec/message_bus/client_spec.rb @@ -113,4 +113,20 @@ def write_message(message, user = 'message_bus-client') subject.resume expect(result).to eq(true) end + + it 'allows subscription exposing the message_id' do + subject.start + + text = "Hello World! #{Random.rand}" + result = false + subject.subscribe('/message') do |payload, message_id| + result = true if payload['data'] == text + expect(message_id).to be_an Integer + end + + until result + write_message(text) # Keep writing because the message bus might not have started. + sleep(1) + end + end end