Module: Familia::Utils
- Included in:
- Familia
- Defined in:
- lib/familia/utils.rb
Constant Summary collapse
- LENGTH_256_BIT =
[nil, nil] + (2..36).map { |b| calc_length.call(256, b) }
- LENGTH_128_BIT =
[nil, nil] + (2..36).map { |b| calc_length.call(128, b) }
- LENGTH_64_BIT =
[nil, nil] + (2..36).map { |b| calc_length.call(64, b) }
Instance Method Summary collapse
-
#dbkey(*val) ⇒ String
Creates a dbkey from given values.
-
#distinguisher(value_to_distinguish, strict_values: true) ⇒ String?
This method determines the appropriate transformation to apply based on the class of the input argument.
-
#generate_hex_id ⇒ String
Generates a 256-bit cryptographically secure hexadecimal identifier.
-
#generate_hex_trace_id ⇒ String
Generates a 64-bit cryptographically secure hexadecimal trace identifier.
-
#generate_id(base = 36) ⇒ String
Generates a cryptographically secure identifier, encoded in the specified base.
-
#generate_trace_id(base = 36) ⇒ String
Generates a short, secure trace identifier, encoded in the specified base.
-
#join(*val) ⇒ String
Joins array elements with Familia delimiter.
-
#now(name = Time.now) ⇒ Float
Returns current time in UTC as a float.
-
#qstamp(quantum = 10.minutes, pattern: nil, time: nil) ⇒ Integer, String
A quantized timestamp.
-
#serverid(uri) ⇒ Object
Gets server ID without DB component for pool identification.
-
#shorten_to_external_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 128 bits and encodes it in a given base.
-
#shorten_to_trace_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 64 bits and encodes it in a given base.
-
#split(val) ⇒ Array
Splits a string using Familia delimiter.
Instance Method Details
#dbkey(*val) ⇒ String
Creates a dbkey from given values
108 109 110 |
# File 'lib/familia/utils.rb', line 108 def dbkey(*val) join(*val) end |
#distinguisher(value_to_distinguish, strict_values: true) ⇒ String?
This method determines the appropriate transformation to apply based on the class of the input argument.
The method uses a case statement to handle different classes:
- For Symbol, String, Integer, and Float classes, it traces the
operation and converts the value to a string.
- For Familia::Horreum class, it traces the operation and returns the
identifier of the value.
- For TrueClass, FalseClass, and NilClass, it traces the operation and
converts the value to a string (“true”, “false”, or “”).
- For any other class, it traces the operation and returns nil.
Alternative names for value_to_distinguish could be input_value, value,
or object.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/familia/utils.rb', line 179 def distinguisher(value_to_distinguish, strict_values: true) case value_to_distinguish when ::Symbol, ::String, ::Integer, ::Float Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "string", caller(1..1) if Familia.debug? # Symbols and numerics are naturally serializable to strings # so it's a relatively low risk operation. value_to_distinguish.to_s when ::TrueClass, ::FalseClass, ::NilClass Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "true/false/nil", caller(1..1) if Familia.debug? # TrueClass, FalseClass, and NilClass are considered high risk because their # original types cannot be reliably determined from their serialized string # representations. This can lead to unexpected behavior during deserialization. # For instance, a TrueClass value serialized as "true" might be deserialized as # a String, causing application errors. Even more problematic, a NilClass value # serialized as an empty string makes it impossible to distinguish between a # nil value and an empty string upon deserialization. Such scenarios can result # in subtle, hard-to-diagnose bugs. To mitigate these risks, we raise an # exception when encountering these types unless the strict_values option is # explicitly set to false. # raise Familia::HighRiskFactor, value_to_distinguish if strict_values value_to_distinguish.to_s #=> "true", "false", "" when Familia::Base, Class Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "base", caller(1..1) if Familia.debug? # When called with a class we simply transform it to its name. For # instances of Familia class, we store the identifier. if value_to_distinguish.is_a?(Class) value_to_distinguish.name else value_to_distinguish.identifier end else Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "else1 #{strict_values}", caller(1..1) if Familia.debug? if value_to_distinguish.class.ancestors.member?(Familia::Base) Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "isabase", caller(1..1) if Familia.debug? value_to_distinguish.identifier else Familia.trace :TOREDIS_DISTINGUISHER, dbclient, "else2 #{strict_values}", caller(1..1) if Familia.debug? raise Familia::HighRiskFactor, value_to_distinguish if strict_values nil end end end |
#generate_hex_id ⇒ String
Generates a 256-bit cryptographically secure hexadecimal identifier.
14 15 16 |
# File 'lib/familia/utils.rb', line 14 def generate_hex_id SecureRandom.hex(32) end |
#generate_hex_trace_id ⇒ String
64 bits provides ~18 quintillion values, sufficient for request tracing.
Generates a 64-bit cryptographically secure hexadecimal trace identifier.
39 40 41 |
# File 'lib/familia/utils.rb', line 39 def generate_hex_trace_id SecureRandom.hex(8) end |
#generate_id(base = 36) ⇒ String
Generates a cryptographically secure identifier, encoded in the specified base. By default, this creates a compact, URL-safe base-36 string.
30 31 32 33 |
# File 'lib/familia/utils.rb', line 30 def generate_id(base = 36) target_length = LENGTH_256_BIT[base] generate_hex_id.to_i(16).to_s(base).rjust(target_length, '0') end |
#generate_trace_id(base = 36) ⇒ String
Generates a short, secure trace identifier, encoded in the specified base. Suitable for tracing, logging, and other ephemeral use cases.
55 56 57 58 |
# File 'lib/familia/utils.rb', line 55 def generate_trace_id(base = 36) target_length = LENGTH_64_BIT[base] generate_hex_trace_id.to_i(16).to_s(base).rjust(target_length, '0') end |
#join(*val) ⇒ String
Joins array elements with Familia delimiter
94 95 96 |
# File 'lib/familia/utils.rb', line 94 def join(*val) val.compact.join(Familia.delim) end |
#now(name = Time.now) ⇒ Float
Returns current time in UTC as a float
123 124 125 |
# File 'lib/familia/utils.rb', line 123 def now(name = Time.now) name.utc.to_f end |
#qstamp(quantum = 10.minutes, pattern: nil, time: nil) ⇒ Integer, String
A quantized timestamp
142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/familia/utils.rb', line 142 def qstamp(quantum = 10.minutes, pattern: nil, time: nil) time ||= Familia.now time = time.to_f if time.is_a?(Time) rounded = time - (time % quantum) if pattern Time.at(rounded).utc.strftime(pattern) else Time.at(rounded).utc.to_i end end |
#serverid(uri) ⇒ Object
Gets server ID without DB component for pool identification
113 114 115 116 117 118 |
# File 'lib/familia/utils.rb', line 113 def serverid(uri) # Create a copy of URI without DB for server identification uri = uri.dup uri.db = nil uri.serverid end |
#shorten_to_external_id(hex_id, base: 36) ⇒ String
This is useful for creating shorter, public-facing IDs from secure internal ones.
Truncates a 256-bit hexadecimal ID to 128 bits and encodes it in a given base. This function takes the most significant bits from the hex string to maintain randomness while creating a shorter, deterministic identifier.
74 75 76 77 78 |
# File 'lib/familia/utils.rb', line 74 def shorten_to_external_id(hex_id, base: 36) target_length = LENGTH_128_BIT[base] truncated = hex_id.to_i(16) >> (256 - 128) # Always 128 bits truncated.to_s(base).rjust(target_length, '0') end |
#shorten_to_trace_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 64 bits and encodes it in a given base.
85 86 87 88 89 |
# File 'lib/familia/utils.rb', line 85 def shorten_to_trace_id(hex_id, base: 36) target_length = LENGTH_64_BIT[base] truncated = hex_id.to_i(16) >> (256 - 64) # Always 64 bits truncated.to_s(base).rjust(target_length, '0') end |