familia 2.0.0.pre19 → 2.0.0.pre21
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.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +4 -9
- data/.github/workflows/code-smells.yml +64 -3
- data/.pre-commit-config.yaml +8 -6
- data/.reek.yml +10 -9
- data/.rubocop.yml +4 -0
- data/CHANGELOG.rst +177 -112
- data/CLAUDE.md +28 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +20 -17
- data/bin/try +16 -0
- data/bin/tryouts +16 -0
- data/changelog.d/20251105_flexible_external_identifier_format.rst +66 -0
- data/changelog.d/20251107_112554_delano_179_participation_asymmetry.rst +44 -0
- data/changelog.d/20251107_213121_delano_fix_thread_safety_races_011CUumCP492Twxm4NLt2FvL.rst +20 -0
- data/changelog.d/20251107_fix_participates_in_symbol_resolution.rst +91 -0
- data/changelog.d/20251107_optimized_redis_exists_checks.rst +94 -0
- data/changelog.d/20251108_frozen_string_literal_pragma.rst +44 -0
- data/docs/1106-participates_in-bidirectional-solution.md +129 -0
- data/docs/guides/encryption.md +486 -0
- data/docs/guides/feature-encrypted-fields.md +123 -7
- data/docs/guides/feature-expiration.md +161 -117
- data/docs/guides/feature-external-identifiers.md +415 -443
- data/docs/guides/feature-object-identifiers.md +400 -269
- data/docs/guides/feature-quantization.md +120 -6
- data/docs/guides/feature-relationships-indexing.md +318 -0
- data/docs/guides/feature-relationships-methods.md +146 -604
- data/docs/guides/feature-relationships-participation.md +263 -0
- data/docs/guides/feature-relationships.md +118 -136
- data/docs/guides/feature-system-devs.md +176 -693
- data/docs/guides/feature-system.md +119 -6
- data/docs/guides/feature-transient-fields.md +81 -0
- data/docs/guides/field-system.md +778 -0
- data/docs/guides/index.md +32 -15
- data/docs/guides/logging.md +187 -0
- data/docs/guides/optimized-loading.md +674 -0
- data/docs/guides/thread-safety-monitoring.md +61 -0
- data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
- data/docs/migrating/v2.0.0-pre22.md +241 -0
- data/docs/overview.md +7 -9
- data/docs/reference/api-technical.md +267 -320
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
- data/examples/autoloader/mega_customer.rb +2 -0
- data/examples/datatype_standalone.rb +4 -3
- data/examples/encrypted_fields.rb +2 -1
- data/examples/json_usage_patterns.rb +2 -0
- data/examples/relationships.rb +3 -0
- data/examples/safe_dump.rb +2 -1
- data/examples/sampling_demo.rb +53 -0
- data/examples/single_connection_transaction_confusions.rb +2 -1
- data/familia.gemspec +2 -1
- data/lib/familia/base.rb +2 -0
- data/lib/familia/connection/behavior.rb +2 -0
- data/lib/familia/connection/handlers.rb +2 -0
- data/lib/familia/connection/individual_command_proxy.rb +2 -0
- data/lib/familia/connection/middleware.rb +34 -24
- data/lib/familia/connection/operation_core.rb +2 -0
- data/lib/familia/connection/operations.rb +2 -0
- data/lib/familia/connection/pipelined_core.rb +2 -0
- data/lib/familia/connection/transaction_core.rb +68 -0
- data/lib/familia/connection.rb +18 -3
- data/lib/familia/data_type/class_methods.rb +3 -1
- data/lib/familia/data_type/connection.rb +2 -0
- data/lib/familia/data_type/database_commands.rb +2 -0
- data/lib/familia/data_type/serialization.rb +6 -4
- data/lib/familia/data_type/settings.rb +2 -0
- data/lib/familia/data_type/types/counter.rb +2 -0
- data/lib/familia/data_type/types/hashkey.rb +7 -5
- data/lib/familia/data_type/types/listkey.rb +2 -0
- data/lib/familia/data_type/types/lock.rb +2 -0
- data/lib/familia/data_type/types/sorted_set.rb +2 -0
- data/lib/familia/data_type/types/stringkey.rb +2 -0
- data/lib/familia/data_type/types/unsorted_set.rb +2 -0
- data/lib/familia/data_type.rb +2 -0
- data/lib/familia/encryption/encrypted_data.rb +4 -2
- data/lib/familia/encryption/manager.rb +2 -0
- data/lib/familia/encryption/provider.rb +2 -0
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/registry.rb +2 -0
- data/lib/familia/encryption/request_cache.rb +2 -0
- data/lib/familia/encryption.rb +9 -2
- data/lib/familia/errors.rb +2 -0
- data/lib/familia/features/autoloader.rb +2 -0
- data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
- data/lib/familia/features/encrypted_fields.rb +2 -2
- data/lib/familia/features/expiration/extensions.rb +3 -1
- data/lib/familia/features/expiration.rb +12 -4
- data/lib/familia/features/external_identifier.rb +33 -7
- data/lib/familia/features/object_identifier.rb +2 -0
- data/lib/familia/features/quantization.rb +3 -1
- data/lib/familia/features/relationships/README.md +3 -1
- data/lib/familia/features/relationships/collection_operations.rb +2 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +138 -9
- data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +89 -21
- data/lib/familia/features/relationships/indexing.rb +3 -0
- data/lib/familia/features/relationships/indexing_relationship.rb +3 -1
- data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
- data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
- data/lib/familia/features/relationships/participation.rb +155 -69
- data/lib/familia/features/relationships/participation_membership.rb +69 -0
- data/lib/familia/features/relationships/participation_relationship.rb +34 -6
- data/lib/familia/features/relationships/score_encoding.rb +2 -0
- data/lib/familia/features/relationships.rb +5 -3
- data/lib/familia/features/safe_dump.rb +2 -0
- data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
- data/lib/familia/features/transient_fields.rb +2 -0
- data/lib/familia/features.rb +2 -0
- data/lib/familia/field_type.rb +3 -1
- data/lib/familia/horreum/connection.rb +17 -1
- data/lib/familia/horreum/database_commands.rb +2 -0
- data/lib/familia/horreum/definition.rb +16 -6
- data/lib/familia/horreum/management.rb +212 -42
- data/lib/familia/horreum/persistence.rb +176 -108
- data/lib/familia/horreum/related_fields.rb +2 -0
- data/lib/familia/horreum/serialization.rb +23 -4
- data/lib/familia/horreum/settings.rb +2 -0
- data/lib/familia/horreum/utils.rb +2 -0
- data/lib/familia/horreum.rb +15 -1
- data/lib/familia/identifier_extractor.rb +2 -0
- data/lib/familia/instrumentation.rb +156 -0
- data/lib/familia/json_serializer.rb +2 -0
- data/lib/familia/logging.rb +92 -32
- data/lib/familia/refinements/dear_json.rb +2 -0
- data/lib/familia/refinements/stylize_words.rb +2 -14
- data/lib/familia/refinements/time_literals.rb +2 -0
- data/lib/familia/refinements.rb +2 -0
- data/lib/familia/secure_identifier.rb +10 -2
- data/lib/familia/settings.rb +2 -0
- data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
- data/lib/familia/thread_safety/monitor.rb +328 -0
- data/lib/familia/utils.rb +13 -0
- data/lib/familia/verifiable_identifier.rb +3 -1
- data/lib/familia/version.rb +3 -1
- data/lib/familia.rb +31 -4
- data/lib/middleware/database_command_counter.rb +152 -0
- data/lib/middleware/database_logger.rb +295 -170
- data/lib/multi_result.rb +2 -0
- data/try/edge_cases/empty_identifiers_try.rb +2 -0
- data/try/edge_cases/hash_symbolization_try.rb +2 -0
- data/try/edge_cases/json_serialization_try.rb +2 -0
- data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
- data/try/edge_cases/race_conditions_try.rb +4 -0
- data/try/edge_cases/reserved_keywords_try.rb +4 -0
- data/try/edge_cases/string_coercion_try.rb +2 -0
- data/try/edge_cases/ttl_side_effects_try.rb +4 -0
- data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
- data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
- data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
- data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
- data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
- data/try/features/encrypted_fields/memory_security_try.rb +4 -0
- data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
- data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
- data/try/features/encryption/config_persistence_try.rb +4 -0
- data/try/features/encryption/core_try.rb +4 -0
- data/try/features/encryption/instance_variable_scope_try.rb +4 -0
- data/try/features/encryption/module_loading_try.rb +4 -0
- data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
- data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
- data/try/features/encryption/roundtrip_validation_try.rb +4 -0
- data/try/features/encryption/secure_memory_handling_try.rb +4 -0
- data/try/features/expiration/expiration_try.rb +4 -0
- data/try/features/external_identifier/external_identifier_try.rb +171 -8
- data/try/features/feature_dependencies_try.rb +2 -0
- data/try/features/feature_improvements_try.rb +2 -0
- data/try/features/field_groups_try.rb +2 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
- data/try/features/object_identifier/object_identifier_try.rb +2 -0
- data/try/features/quantization/quantization_try.rb +4 -0
- data/try/features/real_feature_integration_try.rb +2 -0
- data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
- data/try/features/relationships/indexing_rebuild_try.rb +600 -0
- data/try/features/relationships/indexing_try.rb +2 -0
- data/try/features/relationships/participation_bidirectional_try.rb +242 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
- data/try/features/relationships/participation_commands_verification_try.rb +2 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
- data/try/features/relationships/participation_reverse_index_try.rb +15 -13
- data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
- data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
- data/try/features/relationships/relationships_api_changes_try.rb +2 -0
- data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
- data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
- data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
- data/try/features/relationships/relationships_performance_try.rb +4 -0
- data/try/features/relationships/relationships_performance_working_try.rb +4 -0
- data/try/features/relationships/relationships_try.rb +6 -4
- data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
- data/try/features/safe_dump/safe_dump_try.rb +4 -0
- data/try/features/transient_fields/redacted_string_try.rb +2 -0
- data/try/features/transient_fields/refresh_reset_try.rb +3 -0
- data/try/features/transient_fields/simple_refresh_test.rb +3 -0
- data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
- data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
- data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
- data/try/integration/connection/fiber_context_preservation_try.rb +4 -0
- data/try/integration/connection/handler_constraints_try.rb +4 -0
- data/try/integration/connection/isolated_dbclient_try.rb +4 -0
- data/try/integration/connection/middleware_reconnect_try.rb +2 -0
- data/try/integration/connection/operation_mode_guards_try.rb +4 -0
- data/try/integration/connection/pipeline_fallback_integration_try.rb +3 -0
- data/try/integration/connection/pools_try.rb +4 -0
- data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
- data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
- data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
- data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
- data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
- data/try/integration/connection/transaction_modes_try.rb +4 -0
- data/try/integration/conventional_inheritance_try.rb +4 -0
- data/try/integration/create_method_try.rb +4 -0
- data/try/integration/cross_component_try.rb +4 -0
- data/try/integration/data_types/datatype_pipelines_try.rb +4 -0
- data/try/integration/data_types/datatype_transactions_try.rb +4 -0
- data/try/integration/database_consistency_try.rb +4 -0
- data/try/integration/familia_extended_try.rb +4 -0
- data/try/integration/familia_members_methods_try.rb +4 -0
- data/try/integration/models/customer_safe_dump_try.rb +4 -0
- data/try/integration/models/customer_try.rb +4 -0
- data/try/integration/models/datatype_base_try.rb +4 -0
- data/try/integration/models/familia_object_try.rb +4 -0
- data/try/integration/persistence_operations_try.rb +4 -0
- data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
- data/try/integration/save_methods_consistency_try.rb +241 -0
- data/try/integration/scenarios_try.rb +4 -0
- data/try/integration/secure_identifier_try.rb +4 -0
- data/try/integration/transaction_safety_core_try.rb +176 -0
- data/try/integration/transaction_safety_workflow_try.rb +291 -0
- data/try/integration/verifiable_identifier_try.rb +4 -0
- data/try/investigation/pipeline_routing/README.md +228 -0
- data/try/performance/benchmarks_try.rb +4 -0
- data/try/performance/transaction_safety_benchmark_try.rb +238 -0
- data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
- data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
- data/try/support/debugging/cache_behavior_tracer.rb +4 -0
- data/try/support/debugging/debug_aad_process.rb +3 -0
- data/try/support/debugging/debug_concealed_internal.rb +3 -0
- data/try/support/debugging/debug_concealed_reveal.rb +3 -0
- data/try/support/debugging/debug_context_aad.rb +3 -0
- data/try/support/debugging/debug_context_simple.rb +3 -0
- data/try/support/debugging/debug_cross_context.rb +3 -0
- data/try/support/debugging/debug_database_load.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
- data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
- data/try/support/debugging/debug_field_decrypt.rb +3 -0
- data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
- data/try/support/debugging/debug_load_path.rb +3 -0
- data/try/support/debugging/debug_method_definition.rb +3 -0
- data/try/support/debugging/debug_method_resolution.rb +3 -0
- data/try/support/debugging/debug_minimal.rb +3 -0
- data/try/support/debugging/debug_provider.rb +3 -0
- data/try/support/debugging/debug_secure_behavior.rb +3 -0
- data/try/support/debugging/debug_string_class.rb +3 -0
- data/try/support/debugging/debug_test.rb +3 -0
- data/try/support/debugging/debug_test_design.rb +3 -0
- data/try/support/debugging/encryption_method_tracer.rb +4 -0
- data/try/support/debugging/provider_diagnostics.rb +4 -0
- data/try/support/helpers/test_cleanup.rb +4 -0
- data/try/support/helpers/test_helpers.rb +5 -0
- data/try/support/memory/memory_basic_test.rb +4 -0
- data/try/support/memory/memory_detailed_test.rb +4 -0
- data/try/support/memory/memory_search_for_string.rb +4 -0
- data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
- data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
- data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
- data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
- data/try/support/prototypes/atomic_saves_v4.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
- data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
- data/try/support/prototypes/pooling/pool_siege.rb +4 -2
- data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
- data/try/thread_safety/README.md +496 -0
- data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
- data/try/thread_safety/connection_chain_race_try.rb +148 -0
- data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
- data/try/thread_safety/feature_registry_race_try.rb +226 -0
- data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
- data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
- data/try/thread_safety/field_registration_race_try.rb +222 -0
- data/try/thread_safety/logger_initialization_race_try.rb +170 -0
- data/try/thread_safety/middleware_registration_race_try.rb +154 -0
- data/try/thread_safety/module_config_race_try.rb +175 -0
- data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
- data/try/unit/core/autoloader_try.rb +4 -0
- data/try/unit/core/base_enhancements_try.rb +4 -0
- data/try/unit/core/connection_try.rb +4 -0
- data/try/unit/core/errors_try.rb +4 -0
- data/try/unit/core/extensions_try.rb +4 -0
- data/try/unit/core/familia_logger_try.rb +2 -0
- data/try/unit/core/familia_try.rb +4 -0
- data/try/unit/core/middleware_sampling_try.rb +335 -0
- data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
- data/try/unit/core/middleware_thread_safety_try.rb +245 -0
- data/try/unit/core/middleware_try.rb +4 -0
- data/try/unit/core/settings_try.rb +4 -0
- data/try/unit/core/time_utils_try.rb +4 -0
- data/try/unit/core/tools_try.rb +4 -0
- data/try/unit/core/utils_try.rb +37 -0
- data/try/unit/data_types/boolean_try.rb +4 -0
- data/try/unit/data_types/counter_try.rb +4 -0
- data/try/unit/data_types/datatype_base_try.rb +4 -0
- data/try/unit/data_types/hash_try.rb +4 -0
- data/try/unit/data_types/list_try.rb +4 -0
- data/try/unit/data_types/lock_try.rb +4 -0
- data/try/unit/data_types/sorted_set_try.rb +4 -0
- data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
- data/try/unit/data_types/string_try.rb +4 -0
- data/try/unit/data_types/unsortedset_try.rb +4 -0
- data/try/unit/familia_resolve_class_try.rb +116 -0
- data/try/unit/horreum/auto_indexing_on_save_try.rb +5 -1
- data/try/unit/horreum/automatic_index_validation_try.rb +2 -0
- data/try/unit/horreum/base_try.rb +4 -0
- data/try/unit/horreum/class_methods_try.rb +4 -0
- data/try/unit/horreum/commands_try.rb +4 -0
- data/try/unit/horreum/defensive_initialization_try.rb +4 -0
- data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +4 -0
- data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
- data/try/unit/horreum/field_categories_try.rb +4 -0
- data/try/unit/horreum/field_definition_try.rb +4 -0
- data/try/unit/horreum/initialization_try.rb +4 -0
- data/try/unit/horreum/json_type_preservation_try.rb +2 -0
- data/try/unit/horreum/optimized_loading_try.rb +156 -0
- data/try/unit/horreum/relations_try.rb +4 -0
- data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
- data/try/unit/horreum/serialization_try.rb +4 -0
- data/try/unit/horreum/settings_try.rb +4 -0
- data/try/unit/horreum/unique_index_edge_cases_try.rb +4 -0
- data/try/unit/horreum/unique_index_guard_validation_try.rb +2 -0
- data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
- data/try/unit/middleware/database_logger_methods_try.rb +251 -0
- data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
- data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
- data/try/unit/thread_safety_monitor_try.rb +149 -0
- metadata +72 -17
- data/.github/workflows/code-quality.yml +0 -138
- data/changelog.d/20251011_012003_delano_159_datatype_transaction_pipeline_support.rst +0 -91
- data/changelog.d/20251011_203905_delano_next.rst +0 -30
- data/changelog.d/20251011_212633_delano_next.rst +0 -13
- data/changelog.d/20251011_221253_delano_next.rst +0 -26
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
- data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
- data/docs/archive/FAMILIA_UPDATE.md +0 -226
- data/docs/archive/README.md +0 -64
- data/docs/archive/api-reference.md +0 -333
- data/docs/guides/core-field-system.md +0 -806
- data/docs/guides/implementation.md +0 -276
- data/docs/guides/security-model.md +0 -183
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# try/unit/thread_safety_monitor_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
require_relative '../support/helpers/test_helpers'
|
|
6
|
+
|
|
7
|
+
# Thread safety monitoring tests
|
|
8
|
+
#
|
|
9
|
+
# Tests basic monitoring functionality without complex concurrency
|
|
10
|
+
|
|
11
|
+
# setup
|
|
12
|
+
Familia.stop_monitoring! if Familia.thread_safety_monitor.enabled
|
|
13
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
14
|
+
|
|
15
|
+
## Monitor starts and stops correctly
|
|
16
|
+
Familia.start_monitoring!
|
|
17
|
+
started = Familia.thread_safety_monitor.enabled
|
|
18
|
+
Familia.stop_monitoring!
|
|
19
|
+
stopped = !Familia.thread_safety_monitor.enabled
|
|
20
|
+
started && stopped
|
|
21
|
+
#=> true
|
|
22
|
+
|
|
23
|
+
## Monitor tracks contentions
|
|
24
|
+
Familia.start_monitoring!
|
|
25
|
+
Familia.thread_safety_monitor.record_contention('test_location')
|
|
26
|
+
Familia.thread_safety_monitor.record_contention('test_location')
|
|
27
|
+
report = Familia.thread_safety_report
|
|
28
|
+
report[:summary][:mutex_contentions]
|
|
29
|
+
#=> 2
|
|
30
|
+
|
|
31
|
+
## Monitor tracks different locations
|
|
32
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
33
|
+
Familia.thread_safety_monitor.record_contention('location_a')
|
|
34
|
+
Familia.thread_safety_monitor.record_contention('location_b')
|
|
35
|
+
Familia.thread_safety_monitor.record_contention('location_a')
|
|
36
|
+
report = Familia.thread_safety_report
|
|
37
|
+
report[:hot_spots].size
|
|
38
|
+
#=> 2
|
|
39
|
+
|
|
40
|
+
## Monitor tracks race conditions
|
|
41
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
42
|
+
Familia.thread_safety_monitor.record_race_condition('test', 'details')
|
|
43
|
+
report = Familia.thread_safety_report
|
|
44
|
+
report[:summary][:race_detections]
|
|
45
|
+
#=> 1
|
|
46
|
+
|
|
47
|
+
## Monitor exports metrics
|
|
48
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
49
|
+
Familia.thread_safety_monitor.record_contention('test')
|
|
50
|
+
metrics = Familia.thread_safety_metrics
|
|
51
|
+
metrics['familia.thread_safety.mutex_contentions']
|
|
52
|
+
#=> 1
|
|
53
|
+
|
|
54
|
+
## Health score starts at maximum
|
|
55
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
56
|
+
report = Familia.thread_safety_report
|
|
57
|
+
report[:health]
|
|
58
|
+
#=> 100
|
|
59
|
+
|
|
60
|
+
## InstrumentedMutex is used for connection chain
|
|
61
|
+
conn_mutex = Familia.instance_variable_get(:@connection_chain_mutex)
|
|
62
|
+
conn_mutex.is_a?(Familia::ThreadSafety::InstrumentedMutex)
|
|
63
|
+
#=> true
|
|
64
|
+
|
|
65
|
+
## InstrumentedMutex tracks basic operations
|
|
66
|
+
mutex = Familia::ThreadSafety::InstrumentedMutex.new('test')
|
|
67
|
+
mutex.synchronize { 'work' }
|
|
68
|
+
stats = mutex.stats
|
|
69
|
+
stats[:lock_count]
|
|
70
|
+
#=> 1
|
|
71
|
+
|
|
72
|
+
## Monitor time_critical_section works
|
|
73
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
74
|
+
result = Familia.thread_safety_monitor.time_critical_section('test') { 37 }
|
|
75
|
+
result
|
|
76
|
+
#=> 37
|
|
77
|
+
|
|
78
|
+
## Critical sections are tracked
|
|
79
|
+
report = Familia.thread_safety_report
|
|
80
|
+
report[:summary][:critical_sections]
|
|
81
|
+
#=> 1
|
|
82
|
+
|
|
83
|
+
## Monitor uses microsecond timing for precision
|
|
84
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
85
|
+
start_μs = Familia.now_in_μs
|
|
86
|
+
Familia.thread_safety_monitor.time_critical_section('timing_test') do
|
|
87
|
+
sleep 0.005 # 5ms sleep
|
|
88
|
+
end
|
|
89
|
+
end_μs = Familia.now_in_μs
|
|
90
|
+
duration_μs = end_μs - start_μs
|
|
91
|
+
# Should be at least 5000 microseconds (5ms)
|
|
92
|
+
duration_μs >= 5000
|
|
93
|
+
#=> true
|
|
94
|
+
|
|
95
|
+
## Wait time tracking uses microsecond precision
|
|
96
|
+
mutex = Familia::ThreadSafety::InstrumentedMutex.new('timing_mutex')
|
|
97
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
98
|
+
|
|
99
|
+
# Create intentional contention with timing
|
|
100
|
+
t1_ready = false
|
|
101
|
+
t2_ready = false
|
|
102
|
+
|
|
103
|
+
t1 = Thread.new do
|
|
104
|
+
mutex.synchronize do
|
|
105
|
+
t1_ready = true
|
|
106
|
+
sleep 0.01 while !t2_ready # Wait for t2 to be waiting
|
|
107
|
+
sleep 0.005 # Hold lock for 5ms
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
t2 = Thread.new do
|
|
112
|
+
sleep 0.001 while !t1_ready # Wait for t1 to acquire lock
|
|
113
|
+
t2_ready = true
|
|
114
|
+
mutex.synchronize { 'got lock' }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
t1.join
|
|
118
|
+
t2.join
|
|
119
|
+
|
|
120
|
+
stats = mutex.stats
|
|
121
|
+
# Should show contention occurred due to intentional delay
|
|
122
|
+
stats[:contention_count] > 0
|
|
123
|
+
#=> true
|
|
124
|
+
|
|
125
|
+
## Monitor preserves microsecond precision
|
|
126
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
127
|
+
Familia.thread_safety_monitor.record_contention('precision_test', 1500) # 1500μs = 1.5ms
|
|
128
|
+
|
|
129
|
+
report = Familia.thread_safety_report
|
|
130
|
+
hot_spot = report[:hot_spots].first
|
|
131
|
+
# Should preserve microsecond precision, not convert to seconds
|
|
132
|
+
hot_spot[:avg_wait_μs]
|
|
133
|
+
#=> 1500
|
|
134
|
+
|
|
135
|
+
## Critical section timing uses microseconds
|
|
136
|
+
Familia.thread_safety_monitor.reset_metrics
|
|
137
|
+
result = Familia.thread_safety_monitor.time_critical_section('precision_timing') do
|
|
138
|
+
sleep 0.003 # 3ms
|
|
139
|
+
37
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
report = Familia.thread_safety_report
|
|
143
|
+
section_perf = report[:section_performance].first
|
|
144
|
+
# Total time should be in microseconds (≥3000μs for 3ms sleep)
|
|
145
|
+
section_perf[:total_time_μs] >= 3000
|
|
146
|
+
#=> true
|
|
147
|
+
|
|
148
|
+
# teardown
|
|
149
|
+
Familia.stop_monitoring!
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: familia
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.
|
|
4
|
+
version: 2.0.0.pre21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Delano Mandelbaum
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.4'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: concurrent-ruby
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.3'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.3'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: connection_pool
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -137,7 +151,6 @@ files:
|
|
|
137
151
|
- ".github/workflows/ci.yml"
|
|
138
152
|
- ".github/workflows/claude-code-review.yml"
|
|
139
153
|
- ".github/workflows/claude.yml"
|
|
140
|
-
- ".github/workflows/code-quality.yml"
|
|
141
154
|
- ".github/workflows/code-smells.yml"
|
|
142
155
|
- ".github/workflows/docs.yml"
|
|
143
156
|
- ".gitignore"
|
|
@@ -153,35 +166,39 @@ files:
|
|
|
153
166
|
- LICENSE.txt
|
|
154
167
|
- README.md
|
|
155
168
|
- bin/irb
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
- changelog.d/
|
|
159
|
-
- changelog.d/
|
|
169
|
+
- bin/try
|
|
170
|
+
- bin/tryouts
|
|
171
|
+
- changelog.d/20251105_flexible_external_identifier_format.rst
|
|
172
|
+
- changelog.d/20251107_112554_delano_179_participation_asymmetry.rst
|
|
173
|
+
- changelog.d/20251107_213121_delano_fix_thread_safety_races_011CUumCP492Twxm4NLt2FvL.rst
|
|
174
|
+
- changelog.d/20251107_fix_participates_in_symbol_resolution.rst
|
|
175
|
+
- changelog.d/20251107_optimized_redis_exists_checks.rst
|
|
176
|
+
- changelog.d/20251108_frozen_string_literal_pragma.rst
|
|
160
177
|
- changelog.d/README.md
|
|
161
178
|
- changelog.d/scriv.ini
|
|
179
|
+
- docs/1106-participates_in-bidirectional-solution.md
|
|
162
180
|
- docs/archive/.gitignore
|
|
163
|
-
- docs/archive/FAMILIA_RELATIONSHIPS.md
|
|
164
|
-
- docs/archive/FAMILIA_TECHNICAL.md
|
|
165
|
-
- docs/archive/FAMILIA_UPDATE.md
|
|
166
|
-
- docs/archive/README.md
|
|
167
|
-
- docs/archive/api-reference.md
|
|
168
181
|
- docs/conf.py
|
|
169
182
|
- docs/guides/.gitignore
|
|
170
|
-
- docs/guides/
|
|
183
|
+
- docs/guides/encryption.md
|
|
171
184
|
- docs/guides/feature-encrypted-fields.md
|
|
172
185
|
- docs/guides/feature-expiration.md
|
|
173
186
|
- docs/guides/feature-external-identifiers.md
|
|
174
187
|
- docs/guides/feature-object-identifiers.md
|
|
175
188
|
- docs/guides/feature-quantization.md
|
|
189
|
+
- docs/guides/feature-relationships-indexing.md
|
|
176
190
|
- docs/guides/feature-relationships-methods.md
|
|
191
|
+
- docs/guides/feature-relationships-participation.md
|
|
177
192
|
- docs/guides/feature-relationships.md
|
|
178
193
|
- docs/guides/feature-system-devs.md
|
|
179
194
|
- docs/guides/feature-system.md
|
|
180
195
|
- docs/guides/feature-transient-fields.md
|
|
181
|
-
- docs/guides/
|
|
196
|
+
- docs/guides/field-system.md
|
|
182
197
|
- docs/guides/index.md
|
|
183
|
-
- docs/guides/
|
|
184
|
-
- docs/guides/
|
|
198
|
+
- docs/guides/logging.md
|
|
199
|
+
- docs/guides/optimized-loading.md
|
|
200
|
+
- docs/guides/thread-safety-monitoring.md
|
|
201
|
+
- docs/guides/time-literals.md
|
|
185
202
|
- docs/migrating/.gitignore
|
|
186
203
|
- docs/migrating/v2.0.0-pre.md
|
|
187
204
|
- docs/migrating/v2.0.0-pre11.md
|
|
@@ -190,6 +207,7 @@ files:
|
|
|
190
207
|
- docs/migrating/v2.0.0-pre14.md
|
|
191
208
|
- docs/migrating/v2.0.0-pre18.md
|
|
192
209
|
- docs/migrating/v2.0.0-pre19.md
|
|
210
|
+
- docs/migrating/v2.0.0-pre22.md
|
|
193
211
|
- docs/migrating/v2.0.0-pre5.md
|
|
194
212
|
- docs/migrating/v2.0.0-pre6.md
|
|
195
213
|
- docs/migrating/v2.0.0-pre7.md
|
|
@@ -204,6 +222,7 @@ files:
|
|
|
204
222
|
- examples/json_usage_patterns.rb
|
|
205
223
|
- examples/relationships.rb
|
|
206
224
|
- examples/safe_dump.rb
|
|
225
|
+
- examples/sampling_demo.rb
|
|
207
226
|
- examples/single_connection_transaction_confusions.rb
|
|
208
227
|
- familia.gemspec
|
|
209
228
|
- lib/familia.rb
|
|
@@ -255,11 +274,14 @@ files:
|
|
|
255
274
|
- lib/familia/features/relationships/collection_operations.rb
|
|
256
275
|
- lib/familia/features/relationships/indexing.rb
|
|
257
276
|
- lib/familia/features/relationships/indexing/multi_index_generators.rb
|
|
277
|
+
- lib/familia/features/relationships/indexing/rebuild_strategies.rb
|
|
258
278
|
- lib/familia/features/relationships/indexing/unique_index_generators.rb
|
|
259
279
|
- lib/familia/features/relationships/indexing_relationship.rb
|
|
260
280
|
- lib/familia/features/relationships/participation.rb
|
|
261
281
|
- lib/familia/features/relationships/participation/participant_methods.rb
|
|
282
|
+
- lib/familia/features/relationships/participation/rebuild_strategies.md
|
|
262
283
|
- lib/familia/features/relationships/participation/target_methods.rb
|
|
284
|
+
- lib/familia/features/relationships/participation_membership.rb
|
|
263
285
|
- lib/familia/features/relationships/participation_relationship.rb
|
|
264
286
|
- lib/familia/features/relationships/score_encoding.rb
|
|
265
287
|
- lib/familia/features/safe_dump.rb
|
|
@@ -279,6 +301,7 @@ files:
|
|
|
279
301
|
- lib/familia/horreum/settings.rb
|
|
280
302
|
- lib/familia/horreum/utils.rb
|
|
281
303
|
- lib/familia/identifier_extractor.rb
|
|
304
|
+
- lib/familia/instrumentation.rb
|
|
282
305
|
- lib/familia/json_serializer.rb
|
|
283
306
|
- lib/familia/logging.rb
|
|
284
307
|
- lib/familia/refinements.rb
|
|
@@ -287,9 +310,12 @@ files:
|
|
|
287
310
|
- lib/familia/refinements/time_literals.rb
|
|
288
311
|
- lib/familia/secure_identifier.rb
|
|
289
312
|
- lib/familia/settings.rb
|
|
313
|
+
- lib/familia/thread_safety/instrumented_mutex.rb
|
|
314
|
+
- lib/familia/thread_safety/monitor.rb
|
|
290
315
|
- lib/familia/utils.rb
|
|
291
316
|
- lib/familia/verifiable_identifier.rb
|
|
292
317
|
- lib/familia/version.rb
|
|
318
|
+
- lib/middleware/database_command_counter.rb
|
|
293
319
|
- lib/middleware/database_logger.rb
|
|
294
320
|
- lib/multi_result.rb
|
|
295
321
|
- pr_agent.toml
|
|
@@ -337,11 +363,15 @@ files:
|
|
|
337
363
|
- try/features/quantization/quantization_try.rb
|
|
338
364
|
- try/features/real_feature_integration_try.rb
|
|
339
365
|
- try/features/relationships/indexing_commands_verification_try.rb
|
|
366
|
+
- try/features/relationships/indexing_rebuild_try.rb
|
|
340
367
|
- try/features/relationships/indexing_try.rb
|
|
368
|
+
- try/features/relationships/participation_bidirectional_try.rb
|
|
341
369
|
- try/features/relationships/participation_commands_verification_spec.rb
|
|
342
370
|
- try/features/relationships/participation_commands_verification_try.rb
|
|
343
371
|
- try/features/relationships/participation_performance_improvements_try.rb
|
|
344
372
|
- try/features/relationships/participation_reverse_index_try.rb
|
|
373
|
+
- try/features/relationships/participation_target_class_resolution_try.rb
|
|
374
|
+
- try/features/relationships/participation_unresolved_target_try.rb
|
|
345
375
|
- try/features/relationships/relationships_api_changes_try.rb
|
|
346
376
|
- try/features/relationships/relationships_edge_cases_try.rb
|
|
347
377
|
- try/features/relationships/relationships_performance_minimal_try.rb
|
|
@@ -384,10 +414,15 @@ files:
|
|
|
384
414
|
- try/integration/models/familia_object_try.rb
|
|
385
415
|
- try/integration/persistence_operations_try.rb
|
|
386
416
|
- try/integration/relationships_persistence_round_trip_try.rb
|
|
417
|
+
- try/integration/save_methods_consistency_try.rb
|
|
387
418
|
- try/integration/scenarios_try.rb
|
|
388
419
|
- try/integration/secure_identifier_try.rb
|
|
420
|
+
- try/integration/transaction_safety_core_try.rb
|
|
421
|
+
- try/integration/transaction_safety_workflow_try.rb
|
|
389
422
|
- try/integration/verifiable_identifier_try.rb
|
|
423
|
+
- try/investigation/pipeline_routing/README.md
|
|
390
424
|
- try/performance/benchmarks_try.rb
|
|
425
|
+
- try/performance/transaction_safety_benchmark_try.rb
|
|
391
426
|
- try/support/benchmarks/deserialization_benchmark.rb
|
|
392
427
|
- try/support/benchmarks/deserialization_correctness_test.rb
|
|
393
428
|
- try/support/debugging/README.md
|
|
@@ -437,6 +472,18 @@ files:
|
|
|
437
472
|
- try/support/prototypes/pooling/lib/visualize_stress_results.rb
|
|
438
473
|
- try/support/prototypes/pooling/pool_siege.rb
|
|
439
474
|
- try/support/prototypes/pooling/run_stress_tests.rb
|
|
475
|
+
- try/thread_safety/README.md
|
|
476
|
+
- try/thread_safety/class_connection_chain_race_try.rb
|
|
477
|
+
- try/thread_safety/connection_chain_race_try.rb
|
|
478
|
+
- try/thread_safety/encryption_manager_cache_race_try.rb
|
|
479
|
+
- try/thread_safety/feature_registry_race_try.rb
|
|
480
|
+
- try/thread_safety/fiber_pipeline_isolation_try.rb
|
|
481
|
+
- try/thread_safety/fiber_transaction_isolation_try.rb
|
|
482
|
+
- try/thread_safety/field_registration_race_try.rb
|
|
483
|
+
- try/thread_safety/logger_initialization_race_try.rb
|
|
484
|
+
- try/thread_safety/middleware_registration_race_try.rb
|
|
485
|
+
- try/thread_safety/module_config_race_try.rb
|
|
486
|
+
- try/thread_safety/secure_identifier_cache_race_try.rb
|
|
440
487
|
- try/unit/core/autoloader_try.rb
|
|
441
488
|
- try/unit/core/base_enhancements_try.rb
|
|
442
489
|
- try/unit/core/connection_try.rb
|
|
@@ -444,6 +491,9 @@ files:
|
|
|
444
491
|
- try/unit/core/extensions_try.rb
|
|
445
492
|
- try/unit/core/familia_logger_try.rb
|
|
446
493
|
- try/unit/core/familia_try.rb
|
|
494
|
+
- try/unit/core/middleware_sampling_try.rb
|
|
495
|
+
- try/unit/core/middleware_test_helpers_bug_try.rb
|
|
496
|
+
- try/unit/core/middleware_thread_safety_try.rb
|
|
447
497
|
- try/unit/core/middleware_try.rb
|
|
448
498
|
- try/unit/core/settings_try.rb
|
|
449
499
|
- try/unit/core/time_utils_try.rb
|
|
@@ -459,6 +509,7 @@ files:
|
|
|
459
509
|
- try/unit/data_types/sorted_set_zadd_options_try.rb
|
|
460
510
|
- try/unit/data_types/string_try.rb
|
|
461
511
|
- try/unit/data_types/unsortedset_try.rb
|
|
512
|
+
- try/unit/familia_resolve_class_try.rb
|
|
462
513
|
- try/unit/horreum/auto_indexing_on_save_try.rb
|
|
463
514
|
- try/unit/horreum/automatic_index_validation_try.rb
|
|
464
515
|
- try/unit/horreum/base_try.rb
|
|
@@ -471,16 +522,20 @@ files:
|
|
|
471
522
|
- try/unit/horreum/field_definition_try.rb
|
|
472
523
|
- try/unit/horreum/initialization_try.rb
|
|
473
524
|
- try/unit/horreum/json_type_preservation_try.rb
|
|
525
|
+
- try/unit/horreum/optimized_loading_try.rb
|
|
474
526
|
- try/unit/horreum/relations_try.rb
|
|
475
527
|
- try/unit/horreum/serialization_persistent_fields_try.rb
|
|
476
528
|
- try/unit/horreum/serialization_try.rb
|
|
477
529
|
- try/unit/horreum/settings_try.rb
|
|
478
530
|
- try/unit/horreum/unique_index_edge_cases_try.rb
|
|
479
531
|
- try/unit/horreum/unique_index_guard_validation_try.rb
|
|
532
|
+
- try/unit/middleware/database_command_counter_methods_try.rb
|
|
533
|
+
- try/unit/middleware/database_logger_methods_try.rb
|
|
480
534
|
- try/unit/refinements/dear_json_array_methods_try.rb
|
|
481
535
|
- try/unit/refinements/dear_json_hash_methods_try.rb
|
|
482
536
|
- try/unit/refinements/time_literals_numeric_methods_try.rb
|
|
483
537
|
- try/unit/refinements/time_literals_string_methods_try.rb
|
|
538
|
+
- try/unit/thread_safety_monitor_try.rb
|
|
484
539
|
- try/valkey.conf
|
|
485
540
|
homepage: https://github.com/delano/familia
|
|
486
541
|
licenses:
|
|
@@ -494,14 +549,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
494
549
|
requirements:
|
|
495
550
|
- - ">="
|
|
496
551
|
- !ruby/object:Gem::Version
|
|
497
|
-
version:
|
|
552
|
+
version: 3.3.6
|
|
498
553
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
499
554
|
requirements:
|
|
500
555
|
- - ">="
|
|
501
556
|
- !ruby/object:Gem::Version
|
|
502
557
|
version: '0'
|
|
503
558
|
requirements: []
|
|
504
|
-
rubygems_version: 3.
|
|
559
|
+
rubygems_version: 3.7.2
|
|
505
560
|
specification_version: 4
|
|
506
561
|
summary: An ORM for Valkey-compatible databases in Ruby.
|
|
507
562
|
test_files: []
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
name: Code Quality
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [ main ]
|
|
6
|
-
push:
|
|
7
|
-
branches: [ main ]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
|
-
pull-requests: write # Needed to post comments on PRs
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
reek:
|
|
16
|
-
name: Reek Code Analysis
|
|
17
|
-
runs-on: ubuntu-24.04
|
|
18
|
-
timeout-minutes: 5
|
|
19
|
-
|
|
20
|
-
steps:
|
|
21
|
-
- name: Checkout code
|
|
22
|
-
uses: actions/checkout@v4
|
|
23
|
-
|
|
24
|
-
- name: Set up Ruby
|
|
25
|
-
uses: ruby/setup-ruby@v1
|
|
26
|
-
with:
|
|
27
|
-
ruby-version: 3.4
|
|
28
|
-
bundler-cache: true
|
|
29
|
-
|
|
30
|
-
- name: Configure Bundler for secure gem installation
|
|
31
|
-
run: |
|
|
32
|
-
bundle config set --local path 'vendor/bundle'
|
|
33
|
-
bundle config set --local deployment 'false'
|
|
34
|
-
|
|
35
|
-
- name: Install dependencies
|
|
36
|
-
run: bundle install
|
|
37
|
-
|
|
38
|
-
- name: Run Reek analysis
|
|
39
|
-
run: |
|
|
40
|
-
echo "=== Running Reek code analysis ==="
|
|
41
|
-
echo "This analysis identifies code smells and potential improvements."
|
|
42
|
-
echo "Results are informational and won't fail the build."
|
|
43
|
-
echo ""
|
|
44
|
-
|
|
45
|
-
# Run reek and capture output (don't fail on warnings)
|
|
46
|
-
# Use success-exit-code to prevent failures from stopping the analysis
|
|
47
|
-
bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
|
|
48
|
-
|
|
49
|
-
echo ""
|
|
50
|
-
echo "=== Reek analysis complete ==="
|
|
51
|
-
continue-on-error: true # Don't fail the build on code smells
|
|
52
|
-
|
|
53
|
-
- name: Generate Reek report (if analysis available)
|
|
54
|
-
run: |
|
|
55
|
-
echo "=== Generating detailed Reek report ==="
|
|
56
|
-
|
|
57
|
-
# Generate JSON report for potential future processing
|
|
58
|
-
bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
|
|
59
|
-
|
|
60
|
-
# Display summary
|
|
61
|
-
if [ -s reek-report.json ]; then
|
|
62
|
-
echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
|
|
63
|
-
echo "Top code smell types found:"
|
|
64
|
-
jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
|
|
65
|
-
else
|
|
66
|
-
echo "No code smells detected or analysis failed"
|
|
67
|
-
fi
|
|
68
|
-
continue-on-error: true
|
|
69
|
-
|
|
70
|
-
- name: Upload Reek report as artifact
|
|
71
|
-
uses: actions/upload-artifact@v4
|
|
72
|
-
if: always()
|
|
73
|
-
with:
|
|
74
|
-
name: reek-report
|
|
75
|
-
path: reek-report.json
|
|
76
|
-
retention-days: 30
|
|
77
|
-
|
|
78
|
-
# Add other code quality checks here
|
|
79
|
-
additional-quality-checks:
|
|
80
|
-
name: Additional Quality Checks
|
|
81
|
-
runs-on: ubuntu-24.04
|
|
82
|
-
timeout-minutes: 5
|
|
83
|
-
|
|
84
|
-
steps:
|
|
85
|
-
- name: Checkout code
|
|
86
|
-
uses: actions/checkout@v4
|
|
87
|
-
|
|
88
|
-
- name: Set up Ruby
|
|
89
|
-
uses: ruby/setup-ruby@v1
|
|
90
|
-
with:
|
|
91
|
-
ruby-version: 3.4
|
|
92
|
-
bundler-cache: true
|
|
93
|
-
|
|
94
|
-
- name: Configure Bundler for secure gem installation
|
|
95
|
-
run: |
|
|
96
|
-
bundle config set --local path 'vendor/bundle'
|
|
97
|
-
bundle config set --local deployment 'false'
|
|
98
|
-
|
|
99
|
-
- name: Install dependencies
|
|
100
|
-
run: bundle install
|
|
101
|
-
|
|
102
|
-
- name: Check for TODO/FIXME comments
|
|
103
|
-
run: |
|
|
104
|
-
echo "=== Scanning for TODO/FIXME comments ==="
|
|
105
|
-
echo "This helps track technical debt and action items."
|
|
106
|
-
echo ""
|
|
107
|
-
|
|
108
|
-
# Find TODO/FIXME comments (excluding this workflow file)
|
|
109
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
110
|
-
xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
|
|
111
|
-
head -20 || echo "No TODO/FIXME comments found"
|
|
112
|
-
continue-on-error: true
|
|
113
|
-
|
|
114
|
-
- name: Check Ruby file syntax
|
|
115
|
-
run: |
|
|
116
|
-
echo "=== Checking Ruby syntax ==="
|
|
117
|
-
echo "Validates that all Ruby files have correct syntax."
|
|
118
|
-
echo ""
|
|
119
|
-
|
|
120
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
121
|
-
while read -r file; do
|
|
122
|
-
if ! ruby -c "$file" > /dev/null 2>&1; then
|
|
123
|
-
echo "Syntax error in: $file"
|
|
124
|
-
ruby -c "$file"
|
|
125
|
-
fi
|
|
126
|
-
done
|
|
127
|
-
continue-on-error: true
|
|
128
|
-
|
|
129
|
-
- name: Check for long lines
|
|
130
|
-
run: |
|
|
131
|
-
echo "=== Checking for long lines (>120 characters) ==="
|
|
132
|
-
echo "Identifies potentially hard-to-read code lines."
|
|
133
|
-
echo ""
|
|
134
|
-
|
|
135
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
136
|
-
xargs grep -Hn "^.\{121,\}$" | \
|
|
137
|
-
head -10 || echo "No overly long lines found"
|
|
138
|
-
continue-on-error: true
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
.. Added
|
|
2
|
-
.. -----
|
|
3
|
-
.. New features and capabilities that have been added.
|
|
4
|
-
|
|
5
|
-
.. Changed
|
|
6
|
-
.. -------
|
|
7
|
-
.. Changes to existing functionality.
|
|
8
|
-
|
|
9
|
-
.. Deprecated
|
|
10
|
-
.. ----------
|
|
11
|
-
.. Soon-to-be removed features.
|
|
12
|
-
|
|
13
|
-
.. Removed
|
|
14
|
-
.. -------
|
|
15
|
-
.. Now removed features.
|
|
16
|
-
|
|
17
|
-
.. Fixed
|
|
18
|
-
.. -----
|
|
19
|
-
.. Bug fixes.
|
|
20
|
-
|
|
21
|
-
.. Security
|
|
22
|
-
.. --------
|
|
23
|
-
.. Security-related improvements.
|
|
24
|
-
|
|
25
|
-
Added
|
|
26
|
-
-----
|
|
27
|
-
|
|
28
|
-
- **DataType Transaction and Pipeline Support** - DataType objects can now initiate transactions and pipelines independently, enabling atomic operations and batch command execution for both parent-owned and standalone DataType objects. `PR #159 <https://github.com/familia/familia/pull/159>`_
|
|
29
|
-
|
|
30
|
-
Key capabilities added:
|
|
31
|
-
|
|
32
|
-
* ``transaction`` method for atomic MULTI/EXEC operations on all DataType classes
|
|
33
|
-
* ``pipelined`` method for batched command execution on all DataType classes
|
|
34
|
-
* Connection chain pattern with Chain of Responsibility for DataType objects
|
|
35
|
-
* Two new connection handlers: ``ParentDelegationHandler`` for owned DataTypes and ``StandaloneConnectionHandler`` for independent DataTypes
|
|
36
|
-
* Enhanced ``direct_access`` method with automatic transaction/pipeline context detection
|
|
37
|
-
* Shared ``Familia::Connection::Behavior`` module extracting common connection functionality
|
|
38
|
-
|
|
39
|
-
This enhancement addresses a critical gap where standalone DataType objects could not guarantee atomicity across multiple operations. A prime example is session storage implementations (similar to Rack::Session stores) where setting session data and expiration must be atomic to prevent memory leaks or security issues. Both parent-owned DataTypes (delegating to parent Horreum objects) and standalone DataTypes now support the full transaction and pipeline API.
|
|
40
|
-
|
|
41
|
-
Example usage:
|
|
42
|
-
|
|
43
|
-
.. code-block:: ruby
|
|
44
|
-
|
|
45
|
-
# Recommended: Use DataType methods for clean, key-free syntax
|
|
46
|
-
# Parent-owned DataType transaction
|
|
47
|
-
user.scores.transaction do
|
|
48
|
-
user.scores.add('level1', 100)
|
|
49
|
-
user.scores.add('level2', 200)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Standalone DataType transaction (e.g., session storage)
|
|
53
|
-
session_store = Familia::StringKey.new('session:abc123')
|
|
54
|
-
session_store.transaction do
|
|
55
|
-
session_store.set(session_data)
|
|
56
|
-
session_store.update_expiration(expiration: 3600)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Pipeline for performance optimization
|
|
60
|
-
leaderboard.pipelined do
|
|
61
|
-
leaderboard.add('player1', 500)
|
|
62
|
-
leaderboard.add('player2', 600)
|
|
63
|
-
leaderboard.size
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Advanced: Connection available for low-level Redis commands when needed
|
|
67
|
-
user.scores.transaction do |conn|
|
|
68
|
-
conn.zadd(user.scores.dbkey, 100, 'level1')
|
|
69
|
-
conn.hset(user.profile.dbkey, 'status', 'active')
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
Changed
|
|
73
|
-
-------
|
|
74
|
-
|
|
75
|
-
- **DataType URI Construction** - DataType objects with ``logical_database`` settings now return clean URIs without custom port information (e.g., ``redis://127.0.0.1/3`` instead of ``redis://127.0.0.1:2525/3``), ensuring consistent URI representation across the library.
|
|
76
|
-
|
|
77
|
-
- **Horreum::Connection Refactored** - The ``Horreum::Connection`` module now includes ``Familia::Connection::Behavior``, eliminating code duplication by sharing URI normalization and connection creation methods between Horreum and DataType. This refactoring improves maintainability while preserving all existing functionality.
|
|
78
|
-
|
|
79
|
-
AI Assistance
|
|
80
|
-
-------------
|
|
81
|
-
|
|
82
|
-
This feature was implemented with significant AI assistance from Claude (Anthropic). The AI helped with:
|
|
83
|
-
|
|
84
|
-
* Architectural design of the connection chain pattern for DataType objects
|
|
85
|
-
* Implementation of the shared Behavior module to extract common functionality
|
|
86
|
-
* Creation of DataType-specific connection handlers (ParentDelegationHandler, StandaloneConnectionHandler)
|
|
87
|
-
* Comprehensive test coverage including transaction and pipeline integration tests
|
|
88
|
-
* Documentation and changelog preparation
|
|
89
|
-
* Debugging and fixing URI formatting edge cases
|
|
90
|
-
|
|
91
|
-
The implementation preserves backward compatibility (all 2,216 existing tests pass) while adding 27 new tests specifically for DataType transaction and pipeline support.
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
.. A new scriv changelog fragment.
|
|
2
|
-
..
|
|
3
|
-
.. Uncomment the section that is right (remove the leading dots).
|
|
4
|
-
.. For top level release notes, leave all the headers commented out.
|
|
5
|
-
..
|
|
6
|
-
Added
|
|
7
|
-
-----
|
|
8
|
-
|
|
9
|
-
- Automatic validation in ``add_to_*`` methods for instance-scoped unique indexes. Previously required manual ``guard_unique_*!`` call before adding to index; now validation happens automatically with clear error messages on duplicate detection.
|
|
10
|
-
|
|
11
|
-
- Transaction detection in ``save()`` method. Raises ``Familia::OperationModeError`` when ``save()`` is called within an existing transaction, since unique index guards need to read current values which is not possible inside MULTI/EXEC blocks.
|
|
12
|
-
|
|
13
|
-
Changed
|
|
14
|
-
-------
|
|
15
|
-
|
|
16
|
-
- Instance-scoped unique index ``add_to_*`` methods now automatically validate uniqueness before adding to parent's index. This matches modern ORM expectations where constraint validation happens implicitly during mutation operations.
|
|
17
|
-
|
|
18
|
-
Documentation
|
|
19
|
-
-------------
|
|
20
|
-
|
|
21
|
-
- Enhanced ``save()`` method documentation to explain transaction restrictions and unique index validation flow.
|
|
22
|
-
|
|
23
|
-
- Updated ``UniqueIndexGenerators`` documentation to clarify that ``add_to_*`` methods perform automatic validation.
|
|
24
|
-
|
|
25
|
-
- Added comprehensive test suite (21 test cases) demonstrating automatic validation behavior, transaction detection, and error handling patterns.
|
|
26
|
-
|
|
27
|
-
AI Assistance
|
|
28
|
-
-------------
|
|
29
|
-
|
|
30
|
-
- Claude Sonnet 4.5 assisted with implementation design, test coverage, and documentation for automatic unique index validation and transaction detection features.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
Changed
|
|
3
|
-
-------
|
|
4
|
-
|
|
5
|
-
- **IndexingRelationship**: Added explicit ``:within`` field to preserve the original DSL parameter, replacing brittle ``target_class`` equality checks with clearer ``within.nil?`` checks. This makes the distinction between class-level and instance-scoped indexes more explicit and prevents potential issues with inheritance scenarios.
|
|
6
|
-
|
|
7
|
-
AI Assistance
|
|
8
|
-
-------------
|
|
9
|
-
|
|
10
|
-
- Design review and architectural analysis by Claude Code (Sonnet 4.5) via second-opinion agent, identifying brittleness in class comparison logic and recommending explicit storage of the ``within`` parameter.
|
|
11
|
-
- Implementation of the ``within`` field addition across IndexingRelationship, generators, and usage sites by Claude Code.
|
|
12
|
-
- All tests verified passing with no behavioral changes.
|
|
13
|
-
..
|