salesforce_streamer 1.2.2 → 2.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88a8ec9604b29ed48acfcf8ac1435fcacf199a7813eba8db8937038874132128
4
- data.tar.gz: 5b7c06be3a4467d41845e76578c95a9bb197a10017ee893eb2acc516b26ffbb0
3
+ metadata.gz: 980626b26a53a56e8fb6fd2028e538ffd667cbe938a1aa1011c4184813d2936d
4
+ data.tar.gz: b6ece556e2e34186b9ad77f445c26ebf6532170e4a9f7a8d0662e309775c9427
5
5
  SHA512:
6
- metadata.gz: 36d5ba79e4af94533266bc9ac52b5110b6a4f6305db9c60a6498b7218d7a5e8c7f48b9db008b582c56877845bb9a498618141da4af0c3e1b77a8173a0640733d
7
- data.tar.gz: d06777105574d0ff430888059ab1d1f61164f520da6b3b5a1c6408e983de3fe22d27fabf575e46a2d7f7ce14936e7af8423b8c7b433a296183a73da8716cd0e9
6
+ metadata.gz: 1920656978db1b707ba61bd90c7026988b99c9dfbb2c7489f4a8554df97f1ad9000885fa619bff884257fd5794225ba3c3ab23b3172b6753ea57ec8f76e6bb05
7
+ data.tar.gz: '0099d97a9cb7774c0fe274b0ee46bb68da87dca38f6113310539248f309111341a4a3e917476e4ca686413cf8cd22e5551f6c917a774a60ffab6541f9ad04889'
@@ -9,10 +9,3 @@ update_configs:
9
9
  allowed_updates:
10
10
  - match:
11
11
  update_type: "all"
12
- automerged_updates:
13
- - match:
14
- dependency_type: "development"
15
- update_type: "all"
16
- - match:
17
- dependency_type: "production"
18
- update_type: "all"
@@ -0,0 +1,67 @@
1
+ # Changelog
2
+
3
+ Sorted so that the most recent change logs are near the top. Only significant
4
+ changes are logged in the change log.
5
+
6
+ ## 2020-08-04 Scott Serok [scott@renofi.com](mailto:scott@renofi.com)
7
+
8
+ v2.0 is released as a major simplification of this library. There are 2
9
+ significant differences from a user's perspective.
10
+
11
+ 1. The YAML configuration requires minor edits to be compatible in v2.0.
12
+ 2. The built-in Redis persistance of the replayId field has been removed. You
13
+ should add a custom middleware and configure the new replay_adapter option.
14
+
15
+ ### PushTopic configuration changes
16
+
17
+ After upgrading to v2, the YAML configuration should be modified. Shift the
18
+ nested "salesforce" block to the left and remove the "salesforce" key.
19
+
20
+ Before v2:
21
+
22
+ name: "TopicName"
23
+ handler: "MyConstant"
24
+ salesforce:
25
+ query: "SELECT Id FROM Lead"
26
+
27
+ As of v2:
28
+
29
+ name: "TopicName"
30
+ handler: "MyConstant"
31
+ query: "SELECT Id FROM Lead"
32
+
33
+ ### Redis Persistance removed
34
+
35
+ The original intention of this library is to manage PushTopic definitions
36
+ and run an event machine that subscribes to the Salesforce Streaming API based
37
+ on those PushTopics.
38
+
39
+ The addition of managing the Replay ID adds unecessary complexity that can be
40
+ incorporated through customization, and so it's been removed. You might use a
41
+ recent commit of v1 of this library for reference how to implement Redis as the
42
+ persistence layer.
43
+
44
+ To record the replayId on every message we can add a piece of middleware
45
+
46
+ class RecordReplayIdMiddleware
47
+ def initialize(handler)
48
+ @handler = handler
49
+ end
50
+
51
+ def call(message)
52
+ @handler.call(message)
53
+ replay_id = message['event']['replayId']
54
+ topic_name = message['topic']
55
+ MyStore.record_replay_id(replay_id, topic_name)
56
+ end
57
+ end
58
+ SalesforceStreamer.config.use_middleware RecordReplayIdMiddleware
59
+
60
+ To retrieve the replayId before subscribing to a PushTopic,
61
+ configure an adapter that returns an integer.
62
+
63
+ SalesforceStreamer.config.replay_adapter = proc { |topic|
64
+ MyStore.fetch_replay_id(topic.name) || -1
65
+ }
66
+
67
+ This will be used to set the replayId value when subscribing to the PushTopic.
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- salesforce_streamer (1.2.2)
5
- faye (= 0.8.9)
6
- restforce (~> 4.2)
4
+ salesforce_streamer (2.0.0.rc1)
5
+ dry-initializer (~> 3.0)
6
+ faye (~> 1.4)
7
+ restforce (>= 4.2, < 6.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -12,7 +13,7 @@ GEM
12
13
  public_suffix (>= 2.0.2, < 5.0)
13
14
  ast (2.4.1)
14
15
  byebug (11.1.3)
15
- codecov (0.2.0)
16
+ codecov (0.2.3)
16
17
  colorize
17
18
  json
18
19
  simplecov
@@ -20,6 +21,7 @@ GEM
20
21
  cookiejar (0.3.3)
21
22
  diff-lcs (1.4.4)
22
23
  docile (1.3.2)
24
+ dry-initializer (3.0.3)
23
25
  em-http-request (1.1.6)
24
26
  addressable (>= 2.3.4)
25
27
  cookiejar (!= 0.3.1)
@@ -29,17 +31,18 @@ GEM
29
31
  em-socksify (0.3.2)
30
32
  eventmachine (>= 1.0.0.beta.4)
31
33
  eventmachine (1.2.7)
32
- faraday (1.0.0)
34
+ faraday (1.0.1)
33
35
  multipart-post (>= 1.2, < 3)
34
36
  faraday_middleware (1.0.0)
35
37
  faraday (~> 1.0)
36
- faye (0.8.9)
38
+ faye (1.4.0)
37
39
  cookiejar (>= 0.3.0)
38
- em-http-request (>= 0.3.0)
40
+ em-http-request (>= 1.1.6)
39
41
  eventmachine (>= 0.12.0)
40
- faye-websocket (>= 0.4.0)
42
+ faye-websocket (>= 0.11.0)
43
+ multi_json (>= 1.0.0)
41
44
  rack (>= 1.0.0)
42
- yajl-ruby (>= 1.0.0)
45
+ websocket-driver (>= 0.5.1)
43
46
  faye-websocket (0.11.0)
44
47
  eventmachine (>= 0.12.0)
45
48
  websocket-driver (>= 0.5.1)
@@ -47,6 +50,7 @@ GEM
47
50
  http_parser.rb (0.6.0)
48
51
  json (2.3.1)
49
52
  jwt (2.2.1)
53
+ multi_json (1.15.0)
50
54
  multipart-post (2.1.1)
51
55
  parallel (1.19.2)
52
56
  parser (2.7.1.4)
@@ -56,11 +60,10 @@ GEM
56
60
  rainbow (3.0.0)
57
61
  rake (13.0.1)
58
62
  regexp_parser (1.7.1)
59
- restforce (4.2.2)
60
- faraday (>= 0.9.0, <= 1.0)
61
- faraday_middleware (>= 0.8.8, <= 1.0)
63
+ restforce (5.0.0)
64
+ faraday (>= 0.9.0, <= 2.0)
65
+ faraday_middleware (>= 0.8.8, <= 2.0)
62
66
  hashie (>= 1.2.0, < 5.0)
63
- json (>= 1.7.5)
64
67
  jwt (>= 1.5.6)
65
68
  rexml (3.2.4)
66
69
  rspec (3.9.0)
@@ -85,9 +88,9 @@ GEM
85
88
  rubocop-ast (>= 0.1.0, < 1.0)
86
89
  ruby-progressbar (~> 1.7)
87
90
  unicode-display_width (>= 1.4.0, < 2.0)
88
- rubocop-ast (0.1.0)
89
- parser (>= 2.7.0.1)
90
- rubocop-performance (1.7.0)
91
+ rubocop-ast (0.3.0)
92
+ parser (>= 2.7.1.4)
93
+ rubocop-performance (1.7.1)
91
94
  rubocop (>= 0.82.0)
92
95
  rubocop-rspec (1.42.0)
93
96
  rubocop (>= 0.87.0)
@@ -100,7 +103,6 @@ GEM
100
103
  websocket-driver (0.7.3)
101
104
  websocket-extensions (>= 0.1.0)
102
105
  websocket-extensions (0.1.5)
103
- yajl-ruby (1.4.1)
104
106
 
105
107
  PLATFORMS
106
108
  ruby
data/README.md CHANGED
@@ -55,12 +55,11 @@ base: &DEFAULT
55
55
  accounts:
56
56
  handler: "AccountChangeHandler"
57
57
  replay: -1
58
- salesforce:
59
- name: "AllAccounts"
60
- api_version: "41.0"
61
- description: "Sync Accounts"
62
- notify_for_fields: "Referenced"
63
- query: "Select Id, Name From Account"
58
+ name: "AllAccounts"
59
+ api_version: "49.0"
60
+ description: "Sync Accounts"
61
+ notify_for_fields: "Referenced"
62
+ query: "Select Id, Name From Account"
64
63
 
65
64
  development:
66
65
  <<: *DEFAULT
@@ -114,12 +113,12 @@ Configure the `SalesforceStreamer` module.
114
113
  ```ruby
115
114
  # config/initializers/salesforce_streamer.rb
116
115
 
117
- require 'redis'
118
- require 'connection_pool'
119
-
120
- SalesforceStreamer.config.redis_connection = ConnectionPool.new(size: 5, timeout: 5) { Redis.new }
121
116
  SalesforceStreamer.config.logger = Logger.new(STDERR, level: 'INFO')
122
117
  SalesforceStreamer.config.exception_adapter = proc { |e| puts e }
118
+ SalesforceStreamer.config.replay_adapter = proc { |topic|
119
+ topic.id || Store.get(topic.name) || topic.replay
120
+ }
121
+ SalesforceStreamer.config.use_middleware AfterMessageReceived
123
122
  SalesforceStreamer.config.manage_topics = true
124
123
  ```
125
124
 
data/Rakefile CHANGED
@@ -5,4 +5,4 @@ require 'rubocop/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
  RuboCop::RakeTask.new
7
7
 
8
- task default: %i[rubocop:auto_correct spec]
8
+ task default: %i[spec rubocop:auto_correct]
@@ -4,16 +4,15 @@ require 'optparse'
4
4
  require 'restforce'
5
5
  require 'yaml'
6
6
  require 'forwardable'
7
+ require 'dry-initializer'
7
8
 
8
9
  require 'salesforce_streamer/configuration'
9
10
  require 'salesforce_streamer/errors'
10
11
  require 'salesforce_streamer/replay_id_error_extension'
11
12
  require 'salesforce_streamer/log'
12
13
  require 'salesforce_streamer/push_topic'
13
- require 'salesforce_streamer/topic_manager'
14
+ require 'salesforce_streamer/salesforce_topic_manager'
14
15
  require 'salesforce_streamer/salesforce_client'
15
- require 'salesforce_streamer/replay_persistence'
16
- require 'salesforce_streamer/redis_replay'
17
16
  require 'salesforce_streamer/server'
18
17
  require 'salesforce_streamer/version'
19
18
  require 'salesforce_streamer/launcher'
@@ -59,10 +58,4 @@ module SalesforceStreamer
59
58
  def self.config
60
59
  Configuration.instance
61
60
  end
62
-
63
- class RedisConnectionError < StandardError
64
- def initialize
65
- super 'SalesforceStreamer.config.redis_connection not set'
66
- end
67
- end
68
61
  end
@@ -1,8 +1,9 @@
1
1
  module SalesforceStreamer
2
2
  # Manages server configuration.
3
3
  class Configuration
4
- attr_accessor :environment, :logger, :require_path, :config_file, :manage_topics,
5
- :server, :exception_adapter, :persistence_adapter, :redis_connection, :middleware
4
+ attr_accessor :environment, :logger, :require_path, :config_file,
5
+ :manage_topics, :exception_adapter, :replay_adapter
6
+ attr_reader :middleware
6
7
 
7
8
  class << self
8
9
  attr_writer :instance
@@ -16,7 +17,7 @@ module SalesforceStreamer
16
17
  @environment = ENV['RACK_ENV'] || :development
17
18
  @logger = Logger.new(IO::NULL)
18
19
  @exception_adapter = proc { |exc| fail(exc) }
19
- @persistence_adapter = RedisReplay.new
20
+ @replay_adapter = proc { |topic| topic.id || topic.replay }
20
21
  @manage_topics = false
21
22
  @config_file = './config/streamer.yml'
22
23
  @require_path = './config/environment'
@@ -27,12 +28,17 @@ module SalesforceStreamer
27
28
  @manage_topics
28
29
  end
29
30
 
31
+ # adds a setup proc to the middleware array
30
32
  def use_middleware(klass, *args, &block)
31
- middleware << proc { |app| klass.new(app, *args, &block) }
33
+ @middleware << [klass, args, block]
32
34
  end
33
35
 
34
- def middleware_chain_for(app)
35
- middleware.reduce(app) { |memo, middleware| middleware.call(memo) }
36
+ # returns a ready to use chain of middleware
37
+ def middleware_runner(last_handler)
38
+ @middleware.reduce(last_handler) do |next_handler, current_handler|
39
+ klass, args, block = current_handler
40
+ klass.new(next_handler, *args, &block)
41
+ end
36
42
  end
37
43
 
38
44
  def push_topic_data
@@ -3,13 +3,13 @@ module SalesforceStreamer
3
3
 
4
4
  class MissingCLIFlagError < StandardError
5
5
  def initialize(flag)
6
- super 'Missing required command line flag: ' + flag.to_s
6
+ super "Missing required command line flag: #{flag}"
7
7
  end
8
8
  end
9
9
 
10
10
  class NilQueryError < StandardError
11
11
  def initialize(name)
12
- super 'Query not defined for ' + name.to_s
12
+ super "Query not defined for #{name}"
13
13
  end
14
14
  end
15
15
 
@@ -21,7 +21,13 @@ module SalesforceStreamer
21
21
 
22
22
  class PushTopicNameTooLongError < StandardError
23
23
  def initialize(name)
24
- super 'PushTopic name: ' + name.to_s + ' (' + name.size.to_s + '/25)'
24
+ super "PushTopic name: #{name} (#{name.size}/25)"
25
+ end
26
+ end
27
+
28
+ class UnprocessableHandlerError < StandardError
29
+ def initialize(constant)
30
+ super "#{constant} does not repond to .call or .perform_async"
25
31
  end
26
32
  end
27
33
  end
@@ -5,14 +5,14 @@ module SalesforceStreamer
5
5
  class Launcher
6
6
  def initialize
7
7
  load_server_configuration
8
- @manager = TopicManager.new push_topics: @push_topics
8
+ @manager = SalesforceTopicManager.new push_topics: @push_topics
9
9
  @server = Server.new push_topics: @push_topics
10
10
  end
11
11
 
12
12
  # Manages each PushTopic configured and starts the Streaming API listener.
13
13
  def run
14
14
  Log.info 'Launching Streamer Services'
15
- @manager.run
15
+ @manager.upsert_topics!
16
16
  @server.push_topics = @manager.push_topics
17
17
  @server.run
18
18
  end
@@ -36,7 +36,7 @@ module SalesforceStreamer
36
36
  @push_topics = []
37
37
  Configuration.instance.push_topic_data.each_value do |topic_data|
38
38
  Log.debug topic_data.to_s
39
- @push_topics << PushTopic.new(data: topic_data)
39
+ @push_topics << PushTopic.new(topic_data.transform_keys(&:to_sym))
40
40
  end
41
41
  end
42
42
  end
@@ -1,38 +1,29 @@
1
1
  module SalesforceStreamer
2
2
  # Models the PushTopic object for both Restforce and Streamer
3
3
  class PushTopic
4
- attr_accessor :id
5
- attr_reader :name, :description, :notify_for_fields, :query,
6
- :handler, :handler_constant, :api_version
4
+ extend Dry::Initializer
7
5
 
8
- def initialize(data:)
9
- @handler = data['handler']
10
- @static_replay = data.dig('replay')&.to_i || -1
11
- @name = data.dig('salesforce', 'name')
12
- @api_version = data.dig('salesforce', 'api_version') || '41.0'
13
- @description = data.dig('salesforce', 'description') || @name
14
- @notify_for_fields = data.dig('salesforce', 'notify_for_fields') || 'Referenced'
15
- @query = strip_spaces(data.dig('salesforce', 'query'))
16
- validate!
17
- end
6
+ option :name
7
+ option :query, proc { |str| str.gsub(/\s+/, ' ') }
8
+ option :handler, proc { |str| prepare_handler_proc Object.const_get(str) }
9
+ option :replay, proc(&:to_i), default: proc { -1 }
10
+ option :api_version, proc(&:to_s), default: proc { '49.0' }
11
+ option :notify_for_fields, default: proc { 'Referenced' }
12
+ option :id, optional: true
13
+ option :description, optional: true
18
14
 
19
- def replay
20
- ReplayPersistence.retrieve(name) || @static_replay
21
- end
15
+ attr_writer :id
22
16
 
23
17
  def handle(message)
24
18
  message['topic'] = @name
25
- handle_chain.call(message)
26
- ReplayPersistence.record @name, message.dig('event', 'replayId')
19
+ message_middleware.call(message)
27
20
  rescue StandardError => e
28
21
  Log.error e
29
22
  Configuration.instance.exception_adapter.call e
30
23
  end
31
24
 
32
- def to_s
33
- "PushTopic id=#{id} name=#{name} handler=#{handler} " \
34
- "replay=#{replay} notify_for_fields=#{notify_for_fields} " \
35
- "description=#{description} api_version=#{api_version} query=#{query}"
25
+ def attributes
26
+ self.class.dry_initializer.public_attributes self
36
27
  end
37
28
 
38
29
  private
@@ -40,29 +31,33 @@ module SalesforceStreamer
40
31
  def validate!
41
32
  fail(PushTopicNameTooLongError, @name) if @name.size > 25
42
33
 
43
- @handler_constant = Object.const_get(@handler)
34
+ @handler = Object.const_get(@handler)
44
35
  true
45
36
  rescue NameError, TypeError => e
46
37
  message = 'handler=' + @handler.to_s + ' exception=' + e.to_s
47
38
  raise(PushTopicHandlerMissingError, message)
48
39
  end
49
40
 
50
- def handle_chain
51
- Configuration.instance.middleware_chain_for(handler_proc)
41
+ def message_middleware
42
+ Configuration.instance.middleware_runner(handler)
52
43
  end
53
44
 
54
- def handler_proc
55
- if handler_constant.respond_to? :perform_async
56
- proc { |message| handler_constant.perform_async message }
57
- else
58
- handler_constant
59
- end
60
- end
45
+ class << self
46
+ def strip_spaces(str)
47
+ fail(NilQueryError, @name) unless str
61
48
 
62
- def strip_spaces(str)
63
- fail(NilQueryError, @name) unless str
49
+ str.gsub(/\s+/, ' ')
50
+ end
64
51
 
65
- str.gsub(/\s+/, ' ')
52
+ def prepare_handler_proc(constant)
53
+ if constant.respond_to? :call
54
+ constant
55
+ elsif constant.respond_to? :perform_async
56
+ proc { |message| handler_constant.perform_async message }
57
+ else
58
+ fail(UnprocessableHandlerError, constant)
59
+ end
60
+ end
66
61
  end
67
62
  end
68
63
  end
@@ -1,5 +1,5 @@
1
1
  module SalesforceStreamer
2
- class TopicManager
2
+ class SalesforceTopicManager
3
3
  attr_reader :push_topics
4
4
 
5
5
  def initialize(push_topics:)
@@ -7,10 +7,11 @@ module SalesforceStreamer
7
7
  @client = SalesforceClient.new
8
8
  end
9
9
 
10
- def run
11
- Log.info 'Running Topic Manager'
10
+ def upsert_topics!
11
+ Log.info 'Starting to upsert PushTopic definitions into Salesforce'
12
12
  @push_topics.each do |push_topic|
13
- Log.debug push_topic.to_s
13
+ Log.info push_topic.name
14
+ Log.debug push_topic.attributes.to_json
14
15
  upsert(push_topic) if diff?(push_topic)
15
16
  end
16
17
  end
@@ -29,12 +30,12 @@ module SalesforceStreamer
29
30
  return true unless push_topic.notify_for_fields.eql?(hashie.NotifyForFields)
30
31
  return true unless push_topic.api_version.to_s.eql?(hashie.ApiVersion.to_s)
31
32
 
32
- Log.debug 'No differences detected'
33
+ Log.info 'No differences detected'
33
34
  false
34
35
  end
35
36
 
36
37
  def upsert(push_topic)
37
- Log.info "Upsert PushTopic #{push_topic.name}"
38
+ Log.info "Upserting PushTopic"
38
39
  if Configuration.instance.manage_topics?
39
40
  @client.upsert_push_topic(push_topic)
40
41
  else
@@ -34,7 +34,8 @@ module SalesforceStreamer
34
34
  def start_em
35
35
  EM.run do
36
36
  @push_topics.map do |topic|
37
- client.subscribe topic.name, replay: topic.replay.to_i do |message|
37
+ replay_id = Configuration.instance.replay_adapter.call(topic)
38
+ client.subscribe topic.name, replay: replay_id.to_i do |message|
38
39
  replay_id = message.dig('event', 'replayId')
39
40
  Log.info "Message #{replay_id} received from topic #{topic.name}"
40
41
  topic.handle message
@@ -1,3 +1,3 @@
1
1
  module SalesforceStreamer
2
- VERSION = '1.2.2'.freeze
2
+ VERSION = '2.0.0.rc1'.freeze
3
3
  end
@@ -24,8 +24,9 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = '>= 2.6'
26
26
 
27
- spec.add_dependency 'faye', '0.8.9'
28
- spec.add_dependency 'restforce', '~> 4.2'
27
+ spec.add_dependency 'dry-initializer', '~> 3.0'
28
+ spec.add_dependency 'faye', '~> 1.4'
29
+ spec.add_dependency 'restforce', '>= 4.2', '< 6.0'
29
30
 
30
31
  spec.add_development_dependency 'byebug'
31
32
  spec.add_development_dependency 'codecov'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salesforce_streamer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Serok
@@ -9,36 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-08-03 00:00:00.000000000 Z
12
+ date: 2020-08-04 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: dry-initializer
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3.0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: faye
16
30
  requirement: !ruby/object:Gem::Requirement
17
31
  requirements:
18
- - - '='
32
+ - - "~>"
19
33
  - !ruby/object:Gem::Version
20
- version: 0.8.9
34
+ version: '1.4'
21
35
  type: :runtime
22
36
  prerelease: false
23
37
  version_requirements: !ruby/object:Gem::Requirement
24
38
  requirements:
25
- - - '='
39
+ - - "~>"
26
40
  - !ruby/object:Gem::Version
27
- version: 0.8.9
41
+ version: '1.4'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: restforce
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
- - - "~>"
46
+ - - ">="
33
47
  - !ruby/object:Gem::Version
34
48
  version: '4.2'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '6.0'
35
52
  type: :runtime
36
53
  prerelease: false
37
54
  version_requirements: !ruby/object:Gem::Requirement
38
55
  requirements:
39
- - - "~>"
56
+ - - ">="
40
57
  - !ruby/object:Gem::Version
41
58
  version: '4.2'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '6.0'
42
62
  - !ruby/object:Gem::Dependency
43
63
  name: byebug
44
64
  requirement: !ruby/object:Gem::Requirement
@@ -155,6 +175,7 @@ files:
155
175
  - ".gitignore"
156
176
  - ".rspec"
157
177
  - ".travis.yml"
178
+ - CHANGELOG.md
158
179
  - Gemfile
159
180
  - Gemfile.lock
160
181
  - LICENSE.txt
@@ -169,12 +190,10 @@ files:
169
190
  - lib/salesforce_streamer/launcher.rb
170
191
  - lib/salesforce_streamer/log.rb
171
192
  - lib/salesforce_streamer/push_topic.rb
172
- - lib/salesforce_streamer/redis_replay.rb
173
193
  - lib/salesforce_streamer/replay_id_error_extension.rb
174
- - lib/salesforce_streamer/replay_persistence.rb
175
194
  - lib/salesforce_streamer/salesforce_client.rb
195
+ - lib/salesforce_streamer/salesforce_topic_manager.rb
176
196
  - lib/salesforce_streamer/server.rb
177
- - lib/salesforce_streamer/topic_manager.rb
178
197
  - lib/salesforce_streamer/version.rb
179
198
  - salesforce_streamer.gemspec
180
199
  homepage: https://github.com/renofi/salesforce_streamer
@@ -194,9 +213,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
213
  version: '2.6'
195
214
  required_rubygems_version: !ruby/object:Gem::Requirement
196
215
  requirements:
197
- - - ">="
216
+ - - ">"
198
217
  - !ruby/object:Gem::Version
199
- version: '0'
218
+ version: 1.3.1
200
219
  requirements: []
201
220
  rubygems_version: 3.1.2
202
221
  signing_key:
@@ -1,55 +0,0 @@
1
- module SalesforceStreamer
2
- class RedisReplay
3
- class << self
4
- def redis_connection
5
- @redis_connection ||= Configuration.instance.redis_connection || fail(RedisConnectionError)
6
- end
7
-
8
- attr_writer :redis_connection
9
- end
10
-
11
- def connection
12
- if RedisReplay.redis_connection.respond_to?(:with)
13
- RedisReplay.redis_connection.with do |conn|
14
- yield(conn)
15
- end
16
- else
17
- yield RedisReplay.redis_connection
18
- end
19
- end
20
-
21
- # Saves the value to a key with expiration
22
- def record(key, value)
23
- return unless key && value
24
-
25
- key = namespaced_key(key)
26
- value = Integer(value)
27
- connection { |c| c.setex key, SECONDS_TO_EXPIRE, value }
28
- rescue StandardError => e
29
- Configuration.instance.exception_adapter.call e
30
- nil
31
- end
32
-
33
- def retrieve(key)
34
- return unless key
35
-
36
- key = namespaced_key(key)
37
- value = connection { |c| c.get key }
38
- Integer(value) if value
39
- rescue StandardError => e
40
- Configuration.instance.exception_adapter.call e
41
- nil
42
- end
43
-
44
- private
45
-
46
- def namespaced_key(key)
47
- NAMESPACE + key.to_s
48
- end
49
-
50
- NAMESPACE = 'SalesforceStreamer:'.freeze
51
- SECONDS_TO_EXPIRE = 24 * 60 * 60 # 24 hours
52
- START = 0
53
- STOP = 0
54
- end
55
- end
@@ -1,18 +0,0 @@
1
- module SalesforceStreamer
2
- # Store values for a given key in a sorted sequence
3
- # Retrieves the highest value given a key
4
- class ReplayPersistence
5
- class << self
6
- def record(key, value)
7
- Log.debug { "Recording #{key}=#{value}" }
8
- Configuration.instance.persistence_adapter&.record key, value
9
- end
10
-
11
- def retrieve(key)
12
- Configuration.instance.persistence_adapter&.retrieve(key).tap do |v|
13
- Log.debug { "Retrieved for #{key} #{v || 'nil'}" }
14
- end
15
- end
16
- end
17
- end
18
- end