familia 2.0.0.pre14 → 2.0.0.pre16

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.
Files changed (276) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/code-quality.yml +138 -0
  3. data/.github/workflows/code-smellage.yml +145 -0
  4. data/.github/workflows/docs.yml +31 -8
  5. data/.gitignore +1 -1
  6. data/.pre-commit-config.yaml +7 -1
  7. data/.reek.yml +98 -0
  8. data/.rubocop.yml +48 -10
  9. data/.talismanrc +9 -0
  10. data/.yardopts +18 -13
  11. data/CHANGELOG.rst +66 -6
  12. data/CLAUDE.md +1 -1
  13. data/Gemfile +6 -5
  14. data/Gemfile.lock +99 -23
  15. data/LICENSE.txt +1 -1
  16. data/README.md +285 -85
  17. data/changelog.d/README.md +2 -2
  18. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  19. data/docs/archive/FAMILIA_TECHNICAL.md +41 -41
  20. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  21. data/docs/archive/README.md +3 -2
  22. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  23. data/docs/conf.py +29 -0
  24. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  25. data/docs/guides/feature-encrypted-fields.md +785 -0
  26. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  27. data/docs/guides/feature-external-identifiers.md +637 -0
  28. data/docs/guides/feature-object-identifiers.md +435 -0
  29. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  30. data/docs/guides/feature-relationships-methods.md +684 -0
  31. data/docs/guides/feature-relationships.md +200 -0
  32. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  33. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  34. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  35. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  36. data/docs/guides/index.md +176 -0
  37. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  38. data/docs/migrating/v2.0.0-pre.md +1 -1
  39. data/docs/migrating/v2.0.0-pre11.md +4 -4
  40. data/docs/migrating/v2.0.0-pre12.md +2 -2
  41. data/docs/migrating/v2.0.0-pre13.md +1 -1
  42. data/docs/migrating/v2.0.0-pre5.md +33 -12
  43. data/docs/migrating/v2.0.0-pre6.md +2 -2
  44. data/docs/migrating/v2.0.0-pre7.md +8 -8
  45. data/docs/overview.md +623 -19
  46. data/docs/reference/api-technical.md +1365 -0
  47. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
  48. data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
  49. data/examples/autoloader/mega_customer.rb +3 -1
  50. data/examples/encrypted_fields.rb +378 -0
  51. data/examples/json_usage_patterns.rb +144 -0
  52. data/examples/relationships.rb +13 -13
  53. data/examples/safe_dump.rb +6 -6
  54. data/examples/single_connection_transaction_confusions.rb +379 -0
  55. data/lib/familia/base.rb +49 -10
  56. data/lib/familia/connection/handlers.rb +223 -0
  57. data/lib/familia/connection/individual_command_proxy.rb +64 -0
  58. data/lib/familia/connection/middleware.rb +75 -0
  59. data/lib/familia/connection/operation_core.rb +93 -0
  60. data/lib/familia/connection/operations.rb +277 -0
  61. data/lib/familia/connection/pipeline_core.rb +87 -0
  62. data/lib/familia/connection/transaction_core.rb +100 -0
  63. data/lib/familia/connection.rb +60 -186
  64. data/lib/familia/data_type/commands.rb +53 -51
  65. data/lib/familia/data_type/serialization.rb +108 -107
  66. data/lib/familia/data_type/types/counter.rb +1 -1
  67. data/lib/familia/data_type/types/hashkey.rb +13 -10
  68. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  69. data/lib/familia/data_type/types/lock.rb +3 -2
  70. data/lib/familia/data_type/types/sorted_set.rb +26 -15
  71. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -5
  72. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  73. data/lib/familia/data_type.rb +75 -47
  74. data/lib/familia/distinguisher.rb +85 -0
  75. data/lib/familia/encryption/encrypted_data.rb +15 -24
  76. data/lib/familia/encryption/manager.rb +6 -4
  77. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  78. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  79. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  80. data/lib/familia/encryption/request_cache.rb +7 -7
  81. data/lib/familia/encryption.rb +2 -3
  82. data/lib/familia/errors.rb +9 -3
  83. data/lib/familia/{autoloader.rb → features/autoloader.rb} +49 -23
  84. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  85. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  86. data/lib/familia/features/encrypted_fields.rb +68 -66
  87. data/lib/familia/features/expiration/extensions.rb +61 -0
  88. data/lib/familia/features/expiration.rb +35 -87
  89. data/lib/familia/features/external_identifier.rb +11 -12
  90. data/lib/familia/features/object_identifier.rb +58 -20
  91. data/lib/familia/features/quantization.rb +17 -22
  92. data/lib/familia/features/relationships/README.md +97 -0
  93. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  94. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  95. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +301 -0
  96. data/lib/familia/features/relationships/indexing.rb +176 -256
  97. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  98. data/lib/familia/features/relationships/participation/participant_methods.rb +160 -0
  99. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  100. data/lib/familia/features/relationships/participation.rb +656 -0
  101. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  102. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  103. data/lib/familia/features/relationships.rb +69 -271
  104. data/lib/familia/features/safe_dump.rb +127 -132
  105. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  106. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  107. data/lib/familia/features/transient_fields.rb +5 -5
  108. data/lib/familia/features.rb +21 -21
  109. data/lib/familia/field_type.rb +24 -4
  110. data/lib/familia/horreum/core/connection.rb +229 -26
  111. data/lib/familia/horreum/core/database_commands.rb +27 -17
  112. data/lib/familia/horreum/core/serialization.rb +40 -20
  113. data/lib/familia/horreum/core/utils.rb +2 -1
  114. data/lib/familia/horreum/shared/settings.rb +2 -1
  115. data/lib/familia/horreum/subclass/definition.rb +33 -45
  116. data/lib/familia/horreum/subclass/management.rb +72 -24
  117. data/lib/familia/horreum/subclass/related_fields_management.rb +82 -21
  118. data/lib/familia/horreum.rb +196 -114
  119. data/lib/familia/json_serializer.rb +0 -1
  120. data/lib/familia/logging.rb +11 -114
  121. data/lib/familia/refinements/dear_json.rb +122 -0
  122. data/lib/familia/refinements/logger_trace.rb +20 -17
  123. data/lib/familia/refinements/stylize_words.rb +65 -0
  124. data/lib/familia/refinements/time_literals.rb +60 -52
  125. data/lib/familia/refinements.rb +2 -1
  126. data/lib/familia/secure_identifier.rb +60 -28
  127. data/lib/familia/settings.rb +83 -7
  128. data/lib/familia/utils.rb +5 -87
  129. data/lib/familia/verifiable_identifier.rb +4 -4
  130. data/lib/familia/version.rb +1 -1
  131. data/lib/familia.rb +72 -15
  132. data/lib/middleware/database_middleware.rb +56 -14
  133. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  134. data/try/configuration/scenarios_try.rb +1 -1
  135. data/try/connection/fiber_context_preservation_try.rb +250 -0
  136. data/try/connection/handler_constraints_try.rb +59 -0
  137. data/try/connection/operation_mode_guards_try.rb +208 -0
  138. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  139. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  140. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  141. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  142. data/try/connection/transaction_mode_strict_try.rb +98 -0
  143. data/try/connection/transaction_mode_warn_try.rb +131 -0
  144. data/try/connection/transaction_modes_try.rb +249 -0
  145. data/try/core/autoloader_try.rb +129 -11
  146. data/try/core/connection_try.rb +7 -7
  147. data/try/core/conventional_inheritance_try.rb +130 -0
  148. data/try/core/create_method_try.rb +15 -23
  149. data/try/core/database_consistency_try.rb +10 -10
  150. data/try/core/errors_try.rb +8 -11
  151. data/try/core/familia_extended_try.rb +2 -2
  152. data/try/core/familia_members_methods_try.rb +76 -0
  153. data/try/core/isolated_dbclient_try.rb +165 -0
  154. data/try/core/middleware_try.rb +16 -16
  155. data/try/core/persistence_operations_try.rb +4 -4
  156. data/try/core/pools_try.rb +42 -26
  157. data/try/core/secure_identifier_try.rb +28 -24
  158. data/try/core/time_utils_try.rb +10 -10
  159. data/try/core/tools_try.rb +1 -1
  160. data/try/core/utils_try.rb +2 -2
  161. data/try/data_types/boolean_try.rb +4 -4
  162. data/try/data_types/datatype_base_try.rb +0 -2
  163. data/try/data_types/list_try.rb +10 -10
  164. data/try/data_types/sorted_set_try.rb +5 -5
  165. data/try/data_types/string_try.rb +12 -12
  166. data/try/data_types/unsortedset_try.rb +33 -0
  167. data/try/debugging/cache_behavior_tracer.rb +7 -7
  168. data/try/debugging/debug_aad_process.rb +1 -1
  169. data/try/debugging/debug_concealed_internal.rb +1 -1
  170. data/try/debugging/debug_cross_context.rb +1 -1
  171. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  172. data/try/debugging/encryption_method_tracer.rb +10 -10
  173. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  174. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  175. data/try/encryption/config_persistence_try.rb +2 -2
  176. data/try/encryption/encryption_core_try.rb +19 -19
  177. data/try/encryption/instance_variable_scope_try.rb +1 -1
  178. data/try/encryption/module_loading_try.rb +2 -2
  179. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  180. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  181. data/try/encryption/secure_memory_handling_try.rb +1 -1
  182. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  183. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  184. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  185. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  186. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  187. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  188. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  189. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  190. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  191. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  192. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  193. data/try/features/feature_dependencies_try.rb +3 -3
  194. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  195. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  196. data/try/features/quantization/quantization_try.rb +1 -1
  197. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  198. data/try/features/relationships/indexing_try.rb +433 -0
  199. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  200. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  201. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  202. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  203. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  204. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  205. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  206. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  207. data/try/features/relationships/relationships_performance_try.rb +20 -20
  208. data/try/features/relationships/relationships_try.rb +27 -38
  209. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  210. data/try/features/transient_fields/refresh_reset_try.rb +1 -1
  211. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  212. data/try/helpers/test_cleanup.rb +86 -0
  213. data/try/helpers/test_helpers.rb +3 -3
  214. data/try/horreum/base_try.rb +3 -2
  215. data/try/horreum/commands_try.rb +1 -1
  216. data/try/horreum/destroy_related_fields_cleanup_try.rb +330 -0
  217. data/try/horreum/initialization_try.rb +11 -7
  218. data/try/horreum/relations_try.rb +21 -13
  219. data/try/horreum/serialization_try.rb +12 -11
  220. data/try/integration/cross_component_try.rb +3 -3
  221. data/try/memory/memory_basic_test.rb +1 -1
  222. data/try/memory/memory_docker_ruby_dump.sh +1 -1
  223. data/try/models/customer_safe_dump_try.rb +1 -1
  224. data/try/models/customer_try.rb +8 -10
  225. data/try/models/datatype_base_try.rb +3 -3
  226. data/try/models/familia_object_try.rb +9 -8
  227. data/try/performance/benchmarks_try.rb +2 -2
  228. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  229. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  230. data/try/prototypes/atomic_saves_v4.rb +1 -1
  231. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  232. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  233. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  234. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  235. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  236. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  237. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  238. data/try/prototypes/pooling/pool_siege.rb +11 -11
  239. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  240. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  241. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  242. data/try/refinements/logger_trace_methods_try.rb +44 -0
  243. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  244. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  245. metadata +77 -45
  246. data/.rubocop_todo.yml +0 -208
  247. data/docs/connection_pooling.md +0 -192
  248. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  249. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  250. data/docs/guides/Feature-System-Autoloading.md +0 -228
  251. data/docs/guides/Home.md +0 -116
  252. data/docs/guides/Relationships-Guide.md +0 -737
  253. data/docs/guides/relationships-methods.md +0 -266
  254. data/docs/reference/auditing_database_commands.rb +0 -228
  255. data/examples/permissions.rb +0 -240
  256. data/lib/familia/features/autoloadable.rb +0 -113
  257. data/lib/familia/features/relationships/cascading.rb +0 -437
  258. data/lib/familia/features/relationships/membership.rb +0 -497
  259. data/lib/familia/features/relationships/permission_management.rb +0 -264
  260. data/lib/familia/features/relationships/querying.rb +0 -615
  261. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  262. data/lib/familia/features/relationships/tracking.rb +0 -418
  263. data/lib/familia/refinements/snake_case.rb +0 -40
  264. data/lib/familia/validation/command_recorder.rb +0 -336
  265. data/lib/familia/validation/expectations.rb +0 -519
  266. data/lib/familia/validation/validation_helpers.rb +0 -443
  267. data/lib/familia/validation/validator.rb +0 -412
  268. data/lib/familia/validation.rb +0 -140
  269. data/try/data_types/set_try.rb +0 -33
  270. data/try/features/autoloadable/autoloadable_try.rb +0 -61
  271. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  272. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -111
  273. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  274. data/try/validation/command_validation_try.rb.disabled +0 -207
  275. data/try/validation/performance_validation_try.rb.disabled +0 -324
  276. data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
data/.rubocop_todo.yml DELETED
@@ -1,208 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2025-07-20 01:49:27 UTC using RuboCop version 1.78.0.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 2
10
- # This cop supports safe autocorrection (--autocorrect).
11
- # Configuration parameters: AutoCorrect, AllowBorderComment, AllowMarginComment.
12
- Layout/EmptyComment:
13
- Exclude:
14
- - "lib/familia/base.rb"
15
- - "lib/familia/connection.rb"
16
-
17
- # Offense count: 1
18
- # This cop supports safe autocorrection (--autocorrect).
19
- Layout/EmptyLines:
20
- Exclude:
21
- - "Gemfile"
22
-
23
- # Offense count: 2
24
- # This cop supports safe autocorrection (--autocorrect).
25
- # Configuration parameters: EnforcedStyle.
26
- # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
27
- Layout/EmptyLinesAroundClassBody:
28
- Exclude:
29
- - "lib/familia/data_type/types/list.rb"
30
- - "lib/familia/data_type/types/unsorted_set.rb"
31
-
32
- # Offense count: 1
33
- # This cop supports safe autocorrection (--autocorrect).
34
- Layout/SpaceAfterComma:
35
- Exclude:
36
- - "lib/familia/data_type/types/hashkey.rb"
37
-
38
- # Offense count: 4
39
- # This cop supports safe autocorrection (--autocorrect).
40
- # Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
41
- # NotImplementedExceptions: NotImplementedError
42
- Lint/UnusedMethodArgument:
43
- Exclude:
44
- - "lib/familia/base.rb"
45
- - "lib/middleware/database_middleware.rb"
46
-
47
- # Offense count: 1
48
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
49
- # AllowedMethods: refine
50
- Metrics/BlockLength:
51
- Max: 28
52
-
53
- # Offense count: 2
54
- # Configuration parameters: AllowedMethods, AllowedPatterns.
55
- Metrics/PerceivedComplexity:
56
- Max: 9
57
-
58
- # Offense count: 50
59
- # This cop supports safe autocorrection (--autocorrect).
60
- # Configuration parameters: EnforcedStyle, BlockForwardingName.
61
- # SupportedStyles: anonymous, explicit
62
- Naming/BlockForwarding:
63
- Exclude:
64
- - "lib/familia/data_type/types/list.rb"
65
- - "lib/familia/data_type/types/sorted_set.rb"
66
- - "lib/familia/data_type/types/unsorted_set.rb"
67
- - "lib/familia/refinements/logger_trace.rb"
68
-
69
- # Offense count: 8
70
- # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
71
- # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
72
- Naming/MethodParameterName:
73
- Exclude:
74
- - "lib/familia/horreum/class_methods.rb"
75
- - "lib/familia/data_type/types/sorted_set.rb"
76
- - "lib/familia/data_type/types/unsorted_set.rb"
77
-
78
- # Offense count: 1
79
- # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
80
- # AllowedMethods: call
81
- # WaywardPredicates: nonzero?
82
- Naming/PredicateMethod:
83
- Exclude:
84
- - "lib/familia/horreum/class_methods.rb"
85
-
86
- # Offense count: 1
87
- # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
88
- # NamePrefix: is_, has_, have_, does_
89
- # ForbiddenPrefixes: is_, has_, have_, does_
90
- # AllowedMethods: is_a?
91
- # MethodDefinitionMacros: define_method, define_singleton_method
92
- Naming/PredicatePrefix:
93
- Exclude:
94
- - "spec/**/*"
95
- - "lib/familia/horreum/class_methods.rb"
96
-
97
- # Offense count: 54
98
- # This cop supports safe autocorrection (--autocorrect).
99
- # Configuration parameters: AllowOnlyRestArgument, UseAnonymousForwarding, RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, RedundantBlockArgumentNames.
100
- # RedundantRestArgumentNames: args, arguments
101
- # RedundantKeywordRestArgumentNames: kwargs, options, opts
102
- # RedundantBlockArgumentNames: blk, block, proc
103
- Style/ArgumentsForwarding:
104
- Exclude:
105
- - "lib/familia/horreum/class_methods.rb"
106
- - "lib/familia/data_type/types/list.rb"
107
- - "lib/familia/data_type/types/sorted_set.rb"
108
- - "lib/familia/data_type/types/unsorted_set.rb"
109
- - "lib/familia/refinements/logger_trace.rb"
110
-
111
- # Offense count: 11
112
- # Configuration parameters: AllowedConstants.
113
- Style/Documentation:
114
- Exclude:
115
- - "spec/**/*"
116
- - "test/**/*"
117
- - "lib/familia/errors.rb"
118
- - "lib/familia/horreum/class_methods.rb"
119
- - "lib/familia/horreum/related_fields_management.rb"
120
- - "lib/familia/data_type/types/hashkey.rb"
121
- - "lib/familia/data_type/types/list.rb"
122
- - "lib/familia/data_type/types/sorted_set.rb"
123
- - "lib/familia/data_type/types/string.rb"
124
- - "lib/familia/data_type/types/unsorted_set.rb"
125
- - "lib/familia/version.rb"
126
-
127
- # Offense count: 1
128
- # This cop supports safe autocorrection (--autocorrect).
129
- # Configuration parameters: AutoCorrect, EnforcedStyle, AllowComments.
130
- # SupportedStyles: empty, nil, both
131
-
132
- # Offense count: 2
133
- # This cop supports safe autocorrection (--autocorrect).
134
- # Configuration parameters: MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
135
- # SupportedStyles: annotated, template, unannotated
136
- Style/FormatStringToken:
137
- EnforcedStyle: unannotated
138
-
139
- # Offense count: 1
140
- # This cop supports unsafe autocorrection (--autocorrect-all).
141
- # Configuration parameters: EnforcedStyle.
142
- # SupportedStyles: always, always_true, never
143
- Style/FrozenStringLiteralComment:
144
- Exclude:
145
- - "**/*.arb"
146
- - "lib/familia/horreum/related_fields_management.rb"
147
-
148
- # Offense count: 1
149
- # This cop supports unsafe autocorrection (--autocorrect-all).
150
- Style/HashTransformValues:
151
- Exclude:
152
- - "lib/familia/data_type/types/hashkey.rb"
153
-
154
- # Offense count: 1
155
- # This cop supports unsafe autocorrection (--autocorrect-all).
156
- # Configuration parameters: EnforcedStyle, Autocorrect.
157
- # SupportedStyles: module_function, extend_self, forbidden
158
-
159
- # Offense count: 1
160
- # This cop supports unsafe autocorrection (--autocorrect-all).
161
- # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
162
- # SupportedStyles: predicate, comparison
163
- Style/NumericPredicate:
164
- Exclude:
165
- - "spec/**/*"
166
- - "lib/familia/horreum/class_methods.rb"
167
-
168
- # Offense count: 1
169
- # This cop supports unsafe autocorrection (--autocorrect-all).
170
-
171
- # Offense count: 1
172
- # This cop supports safe autocorrection (--autocorrect).
173
- # Configuration parameters: EnforcedStyle.
174
- # SupportedStyles: implicit, explicit
175
- Style/RescueStandardError:
176
- Exclude:
177
- - "lib/familia/horreum.rb"
178
-
179
- # Offense count: 1
180
- # This cop supports unsafe autocorrection (--autocorrect-all).
181
- # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
182
- # AllowedMethods: present?, blank?, presence, try, try!
183
- Style/SafeNavigation:
184
- Exclude:
185
- - "lib/familia/connection.rb"
186
-
187
- # Offense count: 4
188
- # Configuration parameters: ActiveSupportClassAttributeAllowed.
189
- ThreadSafety/ClassAndModuleAttributes:
190
- Exclude:
191
- - "lib/familia/base.rb"
192
- - "lib/familia/horreum.rb"
193
- - "lib/middleware/database_middleware.rb"
194
-
195
- # Offense count: 29
196
- ThreadSafety/ClassInstanceVariable:
197
- Exclude:
198
- - "lib/familia/base.rb"
199
- - "lib/familia/horreum/class_methods.rb"
200
- - "lib/familia/version.rb"
201
-
202
- # Offense count: 2
203
- # This cop supports unsafe autocorrection (--autocorrect-all).
204
- # Configuration parameters: EnforcedStyle.
205
- # SupportedStyles: literals, strict
206
- ThreadSafety/MutableClassInstanceVariable:
207
- Exclude:
208
- - "lib/familia/connection.rb"
@@ -1,192 +0,0 @@
1
- # Connection Pooling with Familia
2
-
3
- Familia uses a connection provider pattern for efficient connection pooling. This guide shows how to configure pools for optimal performance with multiple logical databases.
4
-
5
- ## Key Concepts
6
-
7
- - **Connection Provider Contract**: Your provider MUST return connections already on the correct logical database. Familia will NOT issue SELECT commands.
8
- - **URI-based Selection**: Familia passes normalized URIs (e.g., `redis://localhost:6379/2`) encoding the logical database.
9
- - **One Pool Per Database**: Each unique logical database requires its own connection pool.
10
-
11
- ## Basic Setup
12
-
13
- ### Simple Connection Pool
14
-
15
- ```ruby
16
- require 'connection_pool'
17
-
18
- class MyApp
19
- @pools = {}
20
-
21
- Familia.connection_provider = lambda do |uri|
22
- parsed = URI.parse(uri)
23
- pool_key = "#{parsed.host}:#{parsed.port}/#{parsed.db || 0}"
24
-
25
- @pools[pool_key] ||= ConnectionPool.new(size: 10, timeout: 5) do
26
- Redis.new(
27
- host: parsed.host,
28
- port: parsed.port,
29
- db: parsed.db || 0
30
- )
31
- end
32
-
33
- @pools[pool_key].with { |conn| conn }
34
- end
35
- end
36
- ```
37
-
38
- ### Multi-Database Configuration
39
-
40
- ```ruby
41
- class MyApp
42
- POOL_CONFIGS = {
43
- 0 => { size: 20 }, # Main database
44
- 1 => { size: 5 }, # Analytics
45
- 2 => { size: 10 } # Cache
46
- }.freeze
47
-
48
- @pools = {}
49
-
50
- Familia.connection_provider = lambda do |uri|
51
- parsed = URI.parse(uri)
52
- db = parsed.db || 0
53
- pool_key = "#{parsed.host}:#{parsed.port}/#{db}"
54
-
55
- @pools[pool_key] ||= begin
56
- config = POOL_CONFIGS[db] || { size: 5 }
57
- ConnectionPool.new(timeout: 5, **config) do
58
- Redis.new(host: parsed.host, port: parsed.port, db: db)
59
- end
60
- end
61
-
62
- @pools[pool_key].with { |conn| conn }
63
- end
64
- end
65
- ```
66
-
67
- ### Production Setup with Roda
68
-
69
- ```ruby
70
- # config/familia.rb
71
- class FamiliaPoolManager
72
- include Singleton
73
-
74
- def initialize
75
- @pools = {}
76
- end
77
-
78
- def get_connection(uri)
79
- parsed = URI.parse(uri)
80
- pool_key = "#{parsed.host}:#{parsed.port}/#{parsed.db || 0}"
81
-
82
- @pools[pool_key] ||= ConnectionPool.new(
83
- size: pool_size_for_environment,
84
- timeout: 5
85
- ) do
86
- Redis.new(
87
- host: parsed.host,
88
- port: parsed.port,
89
- db: parsed.db || 0,
90
- timeout: 1,
91
- reconnect_attempts: 3
92
- )
93
- end
94
-
95
- @pools[pool_key].with { |conn| conn }
96
- end
97
-
98
- private
99
-
100
- def pool_size_for_environment
101
- if defined?(Sidekiq)
102
- Sidekiq.options[:concurrency] + 2
103
- else
104
- ENV.fetch('WEB_CONCURRENCY', 5).to_i + 2
105
- end
106
- end
107
- end
108
-
109
- # Configure at application startup
110
- Familia.connection_provider = lambda do |uri|
111
- FamiliaPoolManager.instance.get_connection(uri)
112
- end
113
-
114
- # In your Roda app
115
- class App < Roda
116
- plugin :hooks
117
-
118
- before do
119
- # Familia pools are automatically used via connection_provider
120
- end
121
- end
122
- ```
123
-
124
- ## Model Configuration
125
-
126
- Configure models to use different logical databases:
127
-
128
- ```ruby
129
- class Customer < Familia::Horreum
130
- self.logical_database = 0 # Main application data
131
- field :name, :email
132
- end
133
-
134
- class Analytics < Familia::Horreum
135
- self.logical_database = 1 # Analytics data
136
- field :event_type, :timestamp
137
- end
138
-
139
- class Session < Familia::Horreum
140
- self.logical_database = 2 # Session/cache data
141
- feature :expiration
142
- default_expiration 1.hour
143
- field :user_id, :data
144
- end
145
- ```
146
-
147
- ## Performance Benefits
148
-
149
- Without connection pooling, each operation triggers database switches:
150
- ```
151
- SET key value # Connection on DB 0
152
- SELECT 2 # Switch to DB 2
153
- SET key2 value2 # Now on DB 2
154
- SELECT 0 # Switch back
155
- ```
156
-
157
- With proper pooling, connections stay on the correct database:
158
- ```
159
- SET key value # Connection already on DB 0
160
- SET key2 value2 # Different connection, already on DB 2
161
- ```
162
-
163
- ## Pool Sizing Guidelines
164
-
165
- - **Web Applications**: `threads + 2`
166
- - **Background Jobs**: `concurrency + 2`
167
- - **High Traffic DBs**: Scale up based on usage patterns
168
-
169
- ## Testing and Debugging
170
-
171
- Enable debug mode to verify correct database selection:
172
- ```ruby
173
- Familia.debug = true
174
- ```
175
-
176
- Test concurrent access:
177
- ```ruby
178
- threads = 10.times.map do |i|
179
- Thread.new do
180
- 100.times { |j| MyModel.create(value: "test-#{i}-#{j}") }
181
- end
182
- end
183
- threads.each(&:join)
184
- ```
185
-
186
- ## Best Practices
187
-
188
- - Return connections already on the correct database
189
- - Use one pool per unique logical database
190
- - Implement thread-safe pool creation
191
- - Monitor pool usage and adjust sizes accordingly
192
- - Use the `connection_pool` gem for production reliability