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"]
- PACKET_SIZE_REGEXP =
Regexp for inserting packet size into msgpack encoded packet For ruby 1.9 size attribute moves from front to back of packet
RUBY_VERSION < "1.9.0" ? Regexp.new("size\xC0", nil, "n") : Regexp.new("size\xC0$", nil, "n")
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.
69 70 71 |
# File 'lib/right_agent/packets.rb', line 69 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
64 65 66 |
# File 'lib/right_agent/packets.rb', line 64 def received_at @received_at end |
#size ⇒ Object
(Integer) Size of packet in bytes
67 68 69 |
# File 'lib/right_agent/packets.rb', line 67 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
230 231 232 |
# File 'lib/right_agent/packets.rb', line 230 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
91 92 93 |
# File 'lib/right_agent/packets.rb', line 91 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
80 81 82 |
# File 'lib/right_agent/packets.rb', line 80 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
181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/right_agent/packets.rb', line 181 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
201 202 203 204 |
# File 'lib/right_agent/packets.rb', line 201 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
214 215 216 217 218 219 220 221 |
# File 'lib/right_agent/packets.rb', line 214 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
148 149 150 |
# File 'lib/right_agent/packets.rb', line 148 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
246 247 248 |
# File 'lib/right_agent/packets.rb', line 246 def one_way true end |
#recv_version ⇒ Object
Retrieve protocol version of original creator of packet
Return
(Integer) Received protocol version
264 265 266 |
# File 'lib/right_agent/packets.rb', line 264 def recv_version @version[0] end |
#send_version ⇒ Object
Retrieve protocol version of packet for use when sending packet
Return
(Integer) Send protocol version
272 273 274 |
# File 'lib/right_agent/packets.rb', line 272 def send_version @version[1] end |
#send_version=(value) ⇒ Object
Set protocol version of packet for use when sending packet
277 278 279 |
# File 'lib/right_agent/packets.rb', line 277 def send_version=(value) @version[1] = value end |
#target_for_encryption ⇒ Object
Get target to be used for encrypting the packet
Return
- (String)
-
Target
238 239 240 |
# File 'lib/right_agent/packets.rb', line 238 def target_for_encryption nil end |
#to_json(*a) ⇒ Object
Marshal packet into JSON format
Parameters
- a(Array)
-
Arguments
Return
- js(String)
-
Marshalled packet
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/right_agent/packets.rb', line 125 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
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/right_agent/packets.rb', line 102 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 msgpack 0.5.1 the to_msgpack result is a MessagePack::Packer so need to convert to string msg = msg.to_s.sub!(PACKET_SIZE_REGEXP) { |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
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/right_agent/packets.rb', line 160 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
254 255 256 257 258 |
# File 'lib/right_agent/packets.rb', line 254 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 |