Class: RightScale::Packet
Overview
Base class for all packets flowing through the RightNet routers Knows how to dump itself to MessagePack or JSON
Constant Summary collapse
- VERSION =
Current version of protocol
AgentConfig.protocol_version
- DEFAULT_VERSION =
Default version for packet senders unaware of this versioning
0
- GLOBAL =
Shard scope value meaning restrict sending request only to agents with no shard id
0
- NOT_SERIALIZED =
Instance variables that are not serialized because they are only used locally
["received_at"]
Instance Attribute Summary collapse
-
#received_at ⇒ Object
(Float) Time in seconds in Unix-epoch when message was received.
-
#size ⇒ Object
(Integer) Size of packet in bytes.
Class Method Summary collapse
-
.compatible(id) ⇒ Object
Convert serialized AgentIdentity to compatible format.
-
.json_create(o) ⇒ Object
Create packet from unmarshalled JSON data.
-
.msgpack_create(o) ⇒ Object
Create packet from unmarshalled MessagePack data.
Instance Method Summary collapse
-
#enough_precision(value) ⇒ Object
Determine enough precision for floating point value to give at least two significant digits and then convert the value to a decimal digit string of that precision.
-
#id_to_s(id) ⇒ Object
Generate log friendly serialized identity Result marked with leading ‘*’ if not same as original identity.
-
#ids_to_s(ids) ⇒ Object
Generate log friendly serialized identity for one or more ids Limit to 1000 bytes.
-
#initialize ⇒ Packet
constructor
A new instance of Packet.
-
#name ⇒ Object
Name of packet in lower snake case.
-
#one_way ⇒ Object
Whether the packet is one that does not have an associated response.
-
#recv_version ⇒ Object
Retrieve protocol version of original creator of packet.
-
#send_version ⇒ Object
Retrieve protocol version of packet for use when sending packet.
-
#send_version=(value) ⇒ Object
Set protocol version of packet for use when sending packet.
-
#target_for_encryption ⇒ Object
Get target to be used for encrypting the packet.
-
#to_json(*a) ⇒ Object
Marshal packet into JSON format.
-
#to_msgpack(*a) ⇒ Object
Marshal packet into MessagePack format.
-
#to_s(filter = nil, version = nil) ⇒ Object
Generate log representation.
-
#trace ⇒ Object
Generate token used to trace execution of operation across multiple packets.
Constructor Details
#initialize ⇒ Packet
Returns a new instance of Packet.
65 66 67 |
# File 'lib/right_agent/packets.rb', line 65 def initialize raise NotImplementedError.new("#{self.class.name} is an abstract class.") end |
Instance Attribute Details
#received_at ⇒ Object
(Float) Time in seconds in Unix-epoch when message was received
60 61 62 |
# File 'lib/right_agent/packets.rb', line 60 def received_at @received_at end |
#size ⇒ Object
(Integer) Size of packet in bytes
63 64 65 |
# File 'lib/right_agent/packets.rb', line 63 def size @size end |
Class Method Details
.compatible(id) ⇒ Object
Convert serialized AgentIdentity to compatible format
Parameters
- id(String)
-
Serialized identity
Return
- (String)
-
Compatible serialized identity
228 229 230 |
# File 'lib/right_agent/packets.rb', line 228 def self.compatible(id) AgentIdentity.compatible_serialized(id) end |
.json_create(o) ⇒ Object
Create packet from unmarshalled JSON data
Parameters
- o(Hash)
-
MessagePack data
Return
- (Packet)
-
New packet
87 88 89 |
# File 'lib/right_agent/packets.rb', line 87 def self.json_create(o) create(o) end |
.msgpack_create(o) ⇒ Object
Create packet from unmarshalled MessagePack data
Parameters
- o(Hash)
-
MessagePack data
Return
- (Packet)
-
New packet
76 77 78 |
# File 'lib/right_agent/packets.rb', line 76 def self.msgpack_create(o) create(o) end |
Instance Method Details
#enough_precision(value) ⇒ Object
Determine enough precision for floating point value to give at least two significant digits and then convert the value to a decimal digit string of that precision
Parameters
- value(Float)
-
Value to be converted
Return
- (String)
-
Floating point digit string
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/right_agent/packets.rb', line 179 def enough_precision(value) scale = [1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0] enough = lambda { |v| (v >= 10.0 ? 0 : (v >= 1.0 ? 1 : (v >= 0.1 ? 2 : (v >= 0.01 ? 3 : (v > 0.001 ? 4 : (v > 0.0 ? 5 : 0)))))) } digit_str = lambda { |p, v| sprintf("%.#{p}f", (v * scale[p]).round / scale[p])} digit_str.call(enough.call(value), value) end |
#id_to_s(id) ⇒ Object
Generate log friendly serialized identity Result marked with leading ‘*’ if not same as original identity
Parameters
- id(String)
-
Serialized identity
Return
- (String)
-
Log friendly serialized identity
199 200 201 202 |
# File 'lib/right_agent/packets.rb', line 199 def id_to_s(id) modified_id = AgentIdentity.compatible_serialized(id) if id == modified_id then modified_id else "*#{modified_id}" end end |
#ids_to_s(ids) ⇒ Object
Generate log friendly serialized identity for one or more ids Limit to 1000 bytes
Parameters
- ids(Array|String)
-
Serialized identity or array of serialized identities
Return
- (String)
-
Log friendly serialized identity
212 213 214 215 216 217 218 219 |
# File 'lib/right_agent/packets.rb', line 212 def ids_to_s(ids) if ids.is_a?(Array) s = ids.each { |i| id_to_s(i) }.join(', ') s.size > 1000 ? "[#{s[0, 1000]}...]" : "[#{s}]" else id_to_s(ids) end end |
#name ⇒ Object
Name of packet in lower snake case
Return
- (String)
-
Packet name
146 147 148 |
# File 'lib/right_agent/packets.rb', line 146 def name self.class.to_s.split('::').last.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase end |
#one_way ⇒ Object
Whether the packet is one that does not have an associated response
Return
- (Boolean)
-
Defaults to true
244 245 246 |
# File 'lib/right_agent/packets.rb', line 244 def one_way true end |
#recv_version ⇒ Object
Retrieve protocol version of original creator of packet
Return
(Integer) Received protocol version
262 263 264 |
# File 'lib/right_agent/packets.rb', line 262 def recv_version @version[0] end |
#send_version ⇒ Object
Retrieve protocol version of packet for use when sending packet
Return
(Integer) Send protocol version
270 271 272 |
# File 'lib/right_agent/packets.rb', line 270 def send_version @version[1] end |
#send_version=(value) ⇒ Object
Set protocol version of packet for use when sending packet
275 276 277 |
# File 'lib/right_agent/packets.rb', line 275 def send_version=(value) @version[1] = value end |
#target_for_encryption ⇒ Object
Get target to be used for encrypting the packet
Return
- (String)
-
Target
236 237 238 |
# File 'lib/right_agent/packets.rb', line 236 def target_for_encryption nil end |
#to_json(*a) ⇒ Object
Marshal packet into JSON format
Parameters
- a(Array)
-
Arguments
Return
- js(String)
-
Marshalled packet
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/right_agent/packets.rb', line 123 def to_json(*a) # Hack to override RightScale namespace with Nanite for downward compatibility class_name = self.class.name if class_name =~ /^RightScale::(.*)/ class_name = "Nanite::" + Regexp.last_match(1) end js = { 'json_class' => class_name, 'data' => instance_variables.inject({}) do |m, ivar| name = ivar.to_s.sub(/@/, '') m[name] = instance_variable_get(ivar) unless NOT_SERIALIZED.include?(name) m end }.to_json(*a) @size = js.size js = js.chop + ",\"size\":#{@size}}" end |
#to_msgpack(*a) ⇒ Object
Marshal packet into MessagePack format
Parameters
- a(Array)
-
Arguments
Return
- msg(String)
-
Marshalled packet
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/right_agent/packets.rb', line 98 def to_msgpack(*a) msg = { 'msgpack_class' => self.class.name, 'data' => instance_variables.inject({}) do |m, ivar| name = ivar.to_s.sub(/@/, '') m[name] = instance_variable_get(ivar) unless NOT_SERIALIZED.include?(name) m end, 'size' => nil }.to_msgpack(*a) @size = msg.size # For ruby 1.9 size attribute moves from front to back of packet re = RUBY_VERSION < "1.9.0" ? Regexp.new("size\xC0") : Regexp.new("size\xC0$", nil, "n") # For msgpack 0.5.1 the to_msgpack result is a MessagePack::Packer so need to convert to string msg = msg.to_s.sub!(re) { |m| "size" + @size.to_msgpack } msg end |
#to_s(filter = nil, version = nil) ⇒ Object
Generate log representation
Parameters
- filter(Array(Symbol))
-
Attributes to be included in output
- version(Symbol|nil)
-
Version to display: :recv_version, :send_version, or nil meaning none
Return
- log_msg(String)
-
Log representation
158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/right_agent/packets.rb', line 158 def to_s(filter = nil, version = nil) v = send(version) if version v = (v && v != DEFAULT_VERSION) ? " v#{v}" : "" log_msg = "[#{name}#{v}]" duration = if @duration && (filter.nil? || filter.include?(:duration)) ", #{enough_precision(@duration)} sec" elsif @received_at && (filter.nil? || filter.include?(:local_duration)) ", #{enough_precision(Time.now.to_f - @received_at)} sec" end log_msg += " (#{@size.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")} bytes#{duration})" if @size && !@size.to_s.empty? log_msg end |
#trace ⇒ Object
Generate token used to trace execution of operation across multiple packets
Return
- tr(String)
-
Trace token, may be empty
252 253 254 255 256 |
# File 'lib/right_agent/packets.rb', line 252 def trace audit_id = self.respond_to?(:payload) && payload.is_a?(Hash) && (payload['audit_id'] || payload[:audit_id]) tok = self.respond_to?(:token) && token tr = "<#{audit_id || nil}> <#{tok}>" end |