rmessage 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/rmessage/message.rb +81 -0
- data/lib/rmessage/publisher.rb +16 -0
- data/lib/rmessage/subscriber.rb +66 -0
- data/lib/rmessage.rb +59 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 027c26a46e85945a595e17f63f468b7db4bbc5445e62337e72aba85136ebd089
|
4
|
+
data.tar.gz: 5059e66328f264c26c20d42ab152dc4d1486b02f7990a87dec54560f94455def
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7a1371e9e285c7f8313478f8ee7ecdce68d90b411922ed321d634781122a375534278439bfa02c175bfd1448212f08008339ada3b73e23306d27554e56cde21
|
7
|
+
data.tar.gz: ffdc5a57b6e9d5a99f9f22536478c45287076cc03a1fa2ac6ce25778f90b8b9e3f3ea316632a7d771c995f6c97e912ab479f4181010c2ee696513b3d415718b7
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module RMessage
|
2
|
+
# A Message encapsulates a JSON payload that is sent to or received from Redis.
|
3
|
+
class Message
|
4
|
+
|
5
|
+
# @!attribute [r] label
|
6
|
+
# @return [Symbol, String] the label.
|
7
|
+
attr :label
|
8
|
+
|
9
|
+
# @!attribute [r] signature
|
10
|
+
# @return [Integer, String] the signature.
|
11
|
+
attr :signature
|
12
|
+
|
13
|
+
# @!attribute [r] payload
|
14
|
+
# @return [Hash] the payload.
|
15
|
+
attr :payload
|
16
|
+
|
17
|
+
# Constructs a new Message
|
18
|
+
# @param opts [Hash] message options
|
19
|
+
# * label [Symbol, String] the Message label
|
20
|
+
# * signature [Integer, String] the Message signature
|
21
|
+
# * payload [Hash, String] the Message data
|
22
|
+
# @param data [Hash, String] message data
|
23
|
+
def initialize(opts = {}, data = nil)
|
24
|
+
@label = opts[:label] || :UNTITLED
|
25
|
+
@signature = opts[:signature] || Druuid.gen
|
26
|
+
@payload = data || opts[:payload]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Read and parse data. Defaults to the Message#payload.
|
30
|
+
# @param data [Hash, String] the data.
|
31
|
+
def read(data = @payload)
|
32
|
+
case data
|
33
|
+
when Hash
|
34
|
+
@label ||= data[:label]
|
35
|
+
@signature ||= data[:signature]
|
36
|
+
@payload ||= data[:payload]
|
37
|
+
when String
|
38
|
+
parsed = Oj.load(data)
|
39
|
+
@label ||= parsed['label']
|
40
|
+
@signature ||= parsed['signature']
|
41
|
+
@payload ||= parsed['payload']
|
42
|
+
else raise TypeError, 'Invalid type for Message#payload'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Build a JSON string using data in this message
|
47
|
+
# @param data [Hash, String] the payload.
|
48
|
+
def build(data = @payload)
|
49
|
+
Oj.dump({ 'label' => @label, 'signature' => @signature, 'payload' => data })
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Copyright (c) 2022, Patrick W.
|
55
|
+
# All rights reserved.
|
56
|
+
#
|
57
|
+
# Redistribution and use in source and binary forms, with or without
|
58
|
+
# modification, are permitted provided that the following conditions are met:
|
59
|
+
#
|
60
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
61
|
+
# list of conditions and the following disclaimer.
|
62
|
+
#
|
63
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
64
|
+
# this list of conditions and the following disclaimer in the documentation
|
65
|
+
# and/or other materials provided with the distribution.
|
66
|
+
#
|
67
|
+
# * Neither the name of the copyright holder nor the names of its
|
68
|
+
# contributors may be used to endorse or promote products derived from
|
69
|
+
# this software without specific prior written permission.
|
70
|
+
#
|
71
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
72
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
73
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
74
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
75
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
76
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
77
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
78
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
79
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
80
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
81
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A module to provide publishing functions to an Object.
|
4
|
+
module RMessage::Publisher
|
5
|
+
# @!attribute [r] channel
|
6
|
+
# @return [String, Integer, Symbol] the channel to publish to
|
7
|
+
attr :channel
|
8
|
+
|
9
|
+
# Publishes a message to the specified redis channel.
|
10
|
+
# @param message [RMessage::Message] the message
|
11
|
+
# @param channel [String, Integer, Symbol] the channel
|
12
|
+
# @param connection_index [Integer] the index of the connection to Redis within the {RMessage::CONNECTION_POOL}
|
13
|
+
def publish(message, channel: @channel, connection_index: 0)
|
14
|
+
RMessage::CONNECTION_POOL[connection_index].publish(channel, message.build)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Utility functions to allow setting up and parsing messages received from Redis publishers.
|
4
|
+
module RMessage::Subscriber
|
5
|
+
# @!attribute [r] channel
|
6
|
+
# @return [String, Symbol, Integer] the channel to subscribe to
|
7
|
+
attr :channel
|
8
|
+
|
9
|
+
# @!attribute [r] events
|
10
|
+
# @return [Hash] a map of event labels to classes
|
11
|
+
attr :events
|
12
|
+
|
13
|
+
# Setup a subscription to a specific Redis channel
|
14
|
+
# @param channel [Symbol, String, Integer] the channel
|
15
|
+
# @param auto_parse [Boolean] should messages be parsed automatically?
|
16
|
+
# @param connection_index [Integer] the index of the redis connection in {RMessage::CONNECTION_POOL}
|
17
|
+
def setup_subscription(channel: @channel, auto_parse: false, connection_index: 0, &_)
|
18
|
+
RMessage::CONNECTION_POOL[connection_index].subscribe(channel) do |event|
|
19
|
+
event.subscribe do
|
20
|
+
puts "Subscribed to #{channel}"
|
21
|
+
end
|
22
|
+
|
23
|
+
if auto_parse
|
24
|
+
event.message { |_, message| parse_message(message) }
|
25
|
+
else
|
26
|
+
event.message { |_, message| yield(message) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def parse_message(message_data)
|
34
|
+
msg = RMessage::Message.new(message_data)
|
35
|
+
msg.read
|
36
|
+
@events[msg.label].new(msg)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Copyright (c) 2022, Patrick W.
|
41
|
+
# All rights reserved.
|
42
|
+
#
|
43
|
+
# Redistribution and use in source and binary forms, with or without
|
44
|
+
# modification, are permitted provided that the following conditions are met:
|
45
|
+
#
|
46
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
47
|
+
# list of conditions and the following disclaimer.
|
48
|
+
#
|
49
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
50
|
+
# this list of conditions and the following disclaimer in the documentation
|
51
|
+
# and/or other materials provided with the distribution.
|
52
|
+
#
|
53
|
+
# * Neither the name of the copyright holder nor the names of its
|
54
|
+
# contributors may be used to endorse or promote products derived from
|
55
|
+
# this software without specific prior written permission.
|
56
|
+
#
|
57
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
58
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
59
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
60
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
61
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
62
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
63
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
64
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
65
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
66
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/lib/rmessage.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Dir[File.dirname(__FILE__)].each { |file| $LOAD_PATH.unshift(file) if File.directory? file }
|
4
|
+
|
5
|
+
require 'druuid'
|
6
|
+
require 'dotenv'
|
7
|
+
require 'redis'
|
8
|
+
require 'oj'
|
9
|
+
|
10
|
+
# Utility modules to make it easier to build Pub/Sub systems in Ruby using Redis.
|
11
|
+
module RMessage
|
12
|
+
# @!attribute [r] CONNECTION_POOL
|
13
|
+
# @return [Array] a pool of connections
|
14
|
+
CONNECTION_POOL = []
|
15
|
+
|
16
|
+
autoload :Broker, 'rmessage/broker'
|
17
|
+
autoload :Publisher, 'rmessage/publisher'
|
18
|
+
autoload :Subscriber, 'rmessage/subscriber'
|
19
|
+
autoload :Message, 'rmessage/message'
|
20
|
+
|
21
|
+
def self.add_connection(opts = {})
|
22
|
+
CONNECTION_POOL << Redis.new(host: opts[:host], port: opts[:port])
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.load_defaults
|
26
|
+
# Load ENV vars.
|
27
|
+
Dotenv.load('.env') if File.exist?('.env')
|
28
|
+
Oj.default_options = { mode: :object, cache_keys: true, cache_strings: true, symbol_keys: false }
|
29
|
+
RMessage.add_connection(host: ENV['RMESSAGE_REDIS_HOST'], port: ENV['RMESSAGE_REDIS_PORT'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Copyright (c) 2022, Patrick W.
|
34
|
+
# All rights reserved.
|
35
|
+
#
|
36
|
+
# Redistribution and use in source and binary forms, with or without
|
37
|
+
# modification, are permitted provided that the following conditions are met:
|
38
|
+
#
|
39
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
40
|
+
# list of conditions and the following disclaimer.
|
41
|
+
#
|
42
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
43
|
+
# this list of conditions and the following disclaimer in the documentation
|
44
|
+
# and/or other materials provided with the distribution.
|
45
|
+
#
|
46
|
+
# * Neither the name of the copyright holder nor the names of its
|
47
|
+
# contributors may be used to endorse or promote products derived from
|
48
|
+
# this software without specific prior written permission.
|
49
|
+
#
|
50
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
51
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
52
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
53
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
54
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
55
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
56
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
57
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
58
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
59
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rmessage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Patrick W.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dotenv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.7'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.7.6
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.7'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.7.6
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: druuid
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.0.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.0.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: oj
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.13'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.13.11
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.13'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.13.11
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: redis
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '4.6'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 4.6.0
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.6'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 4.6.0
|
93
|
+
description:
|
94
|
+
email: Sickday@pm.me
|
95
|
+
executables: []
|
96
|
+
extensions: []
|
97
|
+
extra_rdoc_files: []
|
98
|
+
files:
|
99
|
+
- lib/rmessage.rb
|
100
|
+
- lib/rmessage/message.rb
|
101
|
+
- lib/rmessage/publisher.rb
|
102
|
+
- lib/rmessage/subscriber.rb
|
103
|
+
homepage: https://git.repos.pw/Sickday/rmessage
|
104
|
+
licenses:
|
105
|
+
- BSD-3-Clause
|
106
|
+
metadata:
|
107
|
+
source_code_uri: https://git.repos.pw/Sickday/rmessage
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubygems_version: 3.3.3
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Utility modules to make it easier to build Pub/Sub systems in Ruby using
|
127
|
+
Redis.
|
128
|
+
test_files: []
|