familia 2.0.0.pre15 → 2.0.0.pre17

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 (288) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.github/workflows/code-quality.yml +138 -0
  4. data/.github/workflows/code-smells.yml +85 -0
  5. data/.github/workflows/docs.yml +31 -8
  6. data/.gitignore +3 -1
  7. data/.pre-commit-config.yaml +7 -1
  8. data/.reek.yml +98 -0
  9. data/.rubocop.yml +54 -10
  10. data/.talismanrc +9 -0
  11. data/.yardopts +18 -13
  12. data/CHANGELOG.rst +86 -4
  13. data/CLAUDE.md +39 -1
  14. data/Gemfile +6 -5
  15. data/Gemfile.lock +99 -23
  16. data/LICENSE.txt +1 -1
  17. data/README.md +285 -85
  18. data/changelog.d/README.md +2 -2
  19. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  20. data/docs/archive/FAMILIA_TECHNICAL.md +42 -42
  21. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  22. data/docs/archive/README.md +3 -2
  23. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  24. data/docs/conf.py +29 -0
  25. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  26. data/docs/guides/feature-encrypted-fields.md +785 -0
  27. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  28. data/docs/guides/feature-external-identifiers.md +637 -0
  29. data/docs/guides/feature-object-identifiers.md +435 -0
  30. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  31. data/docs/guides/feature-relationships-methods.md +684 -0
  32. data/docs/guides/feature-relationships.md +200 -0
  33. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  34. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  35. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  36. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  37. data/docs/guides/index.md +176 -0
  38. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  39. data/docs/migrating/v2.0.0-pre.md +1 -1
  40. data/docs/migrating/v2.0.0-pre11.md +2 -2
  41. data/docs/migrating/v2.0.0-pre12.md +2 -2
  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 +624 -20
  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 +7 -7
  54. data/examples/single_connection_transaction_confusions.rb +379 -0
  55. data/lib/familia/base.rb +51 -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/class_methods.rb +63 -0
  65. data/lib/familia/data_type/commands.rb +53 -51
  66. data/lib/familia/data_type/connection.rb +83 -0
  67. data/lib/familia/data_type/serialization.rb +108 -107
  68. data/lib/familia/data_type/settings.rb +96 -0
  69. data/lib/familia/data_type/types/counter.rb +1 -1
  70. data/lib/familia/data_type/types/hashkey.rb +15 -11
  71. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  72. data/lib/familia/data_type/types/lock.rb +3 -2
  73. data/lib/familia/data_type/types/sorted_set.rb +128 -14
  74. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -9
  75. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  76. data/lib/familia/data_type.rb +12 -171
  77. data/lib/familia/distinguisher.rb +85 -0
  78. data/lib/familia/encryption/encrypted_data.rb +15 -24
  79. data/lib/familia/encryption/manager.rb +6 -4
  80. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  81. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  82. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  83. data/lib/familia/encryption/request_cache.rb +7 -7
  84. data/lib/familia/encryption.rb +2 -3
  85. data/lib/familia/errors.rb +9 -3
  86. data/lib/familia/features/autoloader.rb +30 -12
  87. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  88. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  89. data/lib/familia/features/encrypted_fields.rb +71 -66
  90. data/lib/familia/features/expiration/extensions.rb +1 -1
  91. data/lib/familia/features/expiration.rb +31 -26
  92. data/lib/familia/features/external_identifier.rb +57 -19
  93. data/lib/familia/features/object_identifier.rb +134 -25
  94. data/lib/familia/features/quantization.rb +16 -21
  95. data/lib/familia/features/relationships/README.md +97 -0
  96. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  97. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  98. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +306 -0
  99. data/lib/familia/features/relationships/indexing.rb +182 -256
  100. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  101. data/lib/familia/features/relationships/participation/participant_methods.rb +164 -0
  102. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  103. data/lib/familia/features/relationships/participation.rb +656 -0
  104. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  105. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  106. data/lib/familia/features/relationships.rb +65 -266
  107. data/lib/familia/features/safe_dump.rb +127 -130
  108. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  109. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  110. data/lib/familia/features/transient_fields.rb +10 -7
  111. data/lib/familia/features.rb +10 -14
  112. data/lib/familia/field_type.rb +6 -4
  113. data/lib/familia/horreum/connection.rb +297 -0
  114. data/lib/familia/horreum/{core/database_commands.rb → database_commands.rb} +27 -17
  115. data/lib/familia/horreum/{subclass/definition.rb → definition.rb} +139 -74
  116. data/lib/familia/horreum/{subclass/management.rb → management.rb} +73 -27
  117. data/lib/familia/horreum/{core/serialization.rb → persistence.rb} +108 -185
  118. data/lib/familia/horreum/{subclass/related_fields_management.rb → related_fields.rb} +104 -23
  119. data/lib/familia/horreum/serialization.rb +172 -0
  120. data/lib/familia/horreum/{shared/settings.rb → settings.rb} +2 -1
  121. data/lib/familia/horreum/{core/utils.rb → utils.rb} +2 -1
  122. data/lib/familia/horreum.rb +222 -119
  123. data/lib/familia/json_serializer.rb +0 -1
  124. data/lib/familia/logging.rb +11 -114
  125. data/lib/familia/refinements/dear_json.rb +122 -0
  126. data/lib/familia/refinements/logger_trace.rb +20 -17
  127. data/lib/familia/refinements/stylize_words.rb +65 -0
  128. data/lib/familia/refinements/time_literals.rb +60 -52
  129. data/lib/familia/refinements.rb +2 -1
  130. data/lib/familia/secure_identifier.rb +60 -28
  131. data/lib/familia/settings.rb +83 -7
  132. data/lib/familia/utils.rb +5 -87
  133. data/lib/familia/verifiable_identifier.rb +4 -4
  134. data/lib/familia/version.rb +1 -1
  135. data/lib/familia.rb +72 -14
  136. data/lib/middleware/database_middleware.rb +56 -14
  137. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  138. data/try/configuration/scenarios_try.rb +2 -2
  139. data/try/connection/fiber_context_preservation_try.rb +250 -0
  140. data/try/connection/handler_constraints_try.rb +59 -0
  141. data/try/connection/operation_mode_guards_try.rb +208 -0
  142. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  143. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  144. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  145. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  146. data/try/connection/transaction_mode_strict_try.rb +98 -0
  147. data/try/connection/transaction_mode_warn_try.rb +131 -0
  148. data/try/connection/transaction_modes_try.rb +249 -0
  149. data/try/core/autoloader_try.rb +120 -2
  150. data/try/core/connection_try.rb +10 -10
  151. data/try/core/conventional_inheritance_try.rb +130 -0
  152. data/try/core/create_method_try.rb +15 -23
  153. data/try/core/database_consistency_try.rb +11 -10
  154. data/try/core/errors_try.rb +11 -14
  155. data/try/core/familia_extended_try.rb +2 -2
  156. data/try/core/familia_members_methods_try.rb +76 -0
  157. data/try/core/familia_try.rb +1 -1
  158. data/try/core/isolated_dbclient_try.rb +165 -0
  159. data/try/core/middleware_try.rb +16 -16
  160. data/try/core/persistence_operations_try.rb +4 -4
  161. data/try/core/pools_try.rb +42 -26
  162. data/try/core/secure_identifier_try.rb +28 -24
  163. data/try/core/time_utils_try.rb +10 -10
  164. data/try/core/tools_try.rb +3 -3
  165. data/try/core/utils_try.rb +2 -2
  166. data/try/data_types/boolean_try.rb +4 -4
  167. data/try/data_types/datatype_base_try.rb +0 -2
  168. data/try/data_types/list_try.rb +10 -10
  169. data/try/data_types/sorted_set_try.rb +5 -5
  170. data/try/data_types/sorted_set_zadd_options_try.rb +625 -0
  171. data/try/data_types/string_try.rb +12 -12
  172. data/try/data_types/unsortedset_try.rb +33 -0
  173. data/try/debugging/cache_behavior_tracer.rb +7 -7
  174. data/try/debugging/debug_aad_process.rb +1 -1
  175. data/try/debugging/debug_concealed_internal.rb +1 -1
  176. data/try/debugging/debug_cross_context.rb +1 -1
  177. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  178. data/try/debugging/encryption_method_tracer.rb +10 -10
  179. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  180. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  181. data/try/encryption/config_persistence_try.rb +2 -2
  182. data/try/encryption/encryption_core_try.rb +19 -19
  183. data/try/encryption/instance_variable_scope_try.rb +1 -1
  184. data/try/encryption/module_loading_try.rb +2 -2
  185. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  186. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  187. data/try/encryption/secure_memory_handling_try.rb +1 -1
  188. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  189. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  190. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  191. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  192. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  193. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  194. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  195. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  196. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  197. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  198. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  199. data/try/features/feature_dependencies_try.rb +3 -3
  200. data/try/features/field_groups_try.rb +244 -0
  201. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  202. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  203. data/try/features/quantization/quantization_try.rb +1 -1
  204. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  205. data/try/features/relationships/indexing_try.rb +443 -0
  206. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  207. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  208. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  209. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  210. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  211. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  212. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  213. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  214. data/try/features/relationships/relationships_performance_try.rb +20 -20
  215. data/try/features/relationships/relationships_try.rb +27 -38
  216. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  217. data/try/features/transient_fields/refresh_reset_try.rb +3 -1
  218. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  219. data/try/helpers/test_cleanup.rb +86 -0
  220. data/try/helpers/test_helpers.rb +6 -7
  221. data/try/horreum/auto_indexing_on_save_try.rb +212 -0
  222. data/try/horreum/base_try.rb +3 -2
  223. data/try/horreum/commands_try.rb +3 -1
  224. data/try/horreum/defensive_initialization_try.rb +86 -0
  225. data/try/horreum/destroy_related_fields_cleanup_try.rb +332 -0
  226. data/try/horreum/initialization_try.rb +11 -7
  227. data/try/horreum/relations_try.rb +21 -13
  228. data/try/horreum/serialization_try.rb +12 -11
  229. data/try/horreum/settings_try.rb +2 -0
  230. data/try/integration/cross_component_try.rb +3 -3
  231. data/try/memory/memory_basic_test.rb +1 -1
  232. data/try/memory/memory_docker_ruby_dump.sh +2 -2
  233. data/try/models/customer_safe_dump_try.rb +1 -1
  234. data/try/models/customer_try.rb +13 -15
  235. data/try/models/datatype_base_try.rb +3 -3
  236. data/try/models/familia_object_try.rb +9 -8
  237. data/try/performance/benchmarks_try.rb +2 -2
  238. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  239. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  240. data/try/prototypes/atomic_saves_v4.rb +1 -1
  241. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  242. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  243. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  244. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  245. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  246. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  247. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  248. data/try/prototypes/pooling/pool_siege.rb +11 -11
  249. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  250. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  251. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  252. data/try/refinements/logger_trace_methods_try.rb +44 -0
  253. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  254. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  255. data/try/valkey.conf +26 -0
  256. metadata +92 -52
  257. data/.rubocop_todo.yml +0 -208
  258. data/docs/connection_pooling.md +0 -192
  259. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  260. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  261. data/docs/guides/Feature-System-Autoloading.md +0 -198
  262. data/docs/guides/Home.md +0 -116
  263. data/docs/guides/Relationships-Guide.md +0 -737
  264. data/docs/guides/relationships-methods.md +0 -266
  265. data/docs/reference/auditing_database_commands.rb +0 -228
  266. data/examples/permissions.rb +0 -240
  267. data/lib/familia/features/relationships/cascading.rb +0 -437
  268. data/lib/familia/features/relationships/membership.rb +0 -497
  269. data/lib/familia/features/relationships/permission_management.rb +0 -264
  270. data/lib/familia/features/relationships/querying.rb +0 -615
  271. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  272. data/lib/familia/features/relationships/tracking.rb +0 -418
  273. data/lib/familia/horreum/core/connection.rb +0 -73
  274. data/lib/familia/horreum/core.rb +0 -21
  275. data/lib/familia/refinements/snake_case.rb +0 -40
  276. data/lib/familia/validation/command_recorder.rb +0 -336
  277. data/lib/familia/validation/expectations.rb +0 -519
  278. data/lib/familia/validation/validation_helpers.rb +0 -443
  279. data/lib/familia/validation/validator.rb +0 -412
  280. data/lib/familia/validation.rb +0 -140
  281. data/try/data_types/set_try.rb +0 -33
  282. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  283. data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
  284. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
  285. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  286. data/try/validation/command_validation_try.rb.disabled +0 -207
  287. data/try/validation/performance_validation_try.rb.disabled +0 -324
  288. 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