familia 2.0.0.pre19 → 2.0.0.pre22
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/.talismanrc +5 -1
- data/CHANGELOG.rst +220 -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/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 +3 -2
- data/lib/familia/connection/operations.rb +2 -0
- data/lib/familia/connection/pipelined_core.rb +3 -3
- data/lib/familia/connection/transaction_core.rb +69 -2
- 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 +79 -52
- 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 +7 -10
- data/lib/familia/data_type/types/stringkey.rb +24 -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 +62 -7
- data/lib/familia/features/object_identifier.rb +49 -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 +97 -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 +8 -1
- data/lib/familia/horreum/definition.rb +16 -6
- data/lib/familia/horreum/management.rb +353 -52
- data/lib/familia/horreum/persistence.rb +179 -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 +3 -1
- 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 +61 -31
- 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/count_any_edge_cases_try.rb +486 -0
- data/try/features/count_any_methods_try.rb +197 -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 +305 -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 +140 -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 +606 -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 +9 -3
- data/try/integration/data_types/datatype_transactions_try.rb +17 -7
- 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 +7 -3
- 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 +39 -22
- 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 +6 -2
- 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/serialization_try.rb +386 -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 +6 -1
- 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 +69 -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.pre22
|
|
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,33 @@ files:
|
|
|
153
166
|
- LICENSE.txt
|
|
154
167
|
- README.md
|
|
155
168
|
- bin/irb
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
- changelog.d/20251011_212633_delano_next.rst
|
|
159
|
-
- changelog.d/20251011_221253_delano_next.rst
|
|
169
|
+
- bin/try
|
|
170
|
+
- bin/tryouts
|
|
160
171
|
- changelog.d/README.md
|
|
161
172
|
- changelog.d/scriv.ini
|
|
173
|
+
- docs/1106-participates_in-bidirectional-solution.md
|
|
162
174
|
- 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
175
|
- docs/conf.py
|
|
169
176
|
- docs/guides/.gitignore
|
|
170
|
-
- docs/guides/
|
|
177
|
+
- docs/guides/encryption.md
|
|
171
178
|
- docs/guides/feature-encrypted-fields.md
|
|
172
179
|
- docs/guides/feature-expiration.md
|
|
173
180
|
- docs/guides/feature-external-identifiers.md
|
|
174
181
|
- docs/guides/feature-object-identifiers.md
|
|
175
182
|
- docs/guides/feature-quantization.md
|
|
183
|
+
- docs/guides/feature-relationships-indexing.md
|
|
176
184
|
- docs/guides/feature-relationships-methods.md
|
|
185
|
+
- docs/guides/feature-relationships-participation.md
|
|
177
186
|
- docs/guides/feature-relationships.md
|
|
178
187
|
- docs/guides/feature-system-devs.md
|
|
179
188
|
- docs/guides/feature-system.md
|
|
180
189
|
- docs/guides/feature-transient-fields.md
|
|
181
|
-
- docs/guides/
|
|
190
|
+
- docs/guides/field-system.md
|
|
182
191
|
- docs/guides/index.md
|
|
183
|
-
- docs/guides/
|
|
184
|
-
- docs/guides/
|
|
192
|
+
- docs/guides/logging.md
|
|
193
|
+
- docs/guides/optimized-loading.md
|
|
194
|
+
- docs/guides/thread-safety-monitoring.md
|
|
195
|
+
- docs/guides/time-literals.md
|
|
185
196
|
- docs/migrating/.gitignore
|
|
186
197
|
- docs/migrating/v2.0.0-pre.md
|
|
187
198
|
- docs/migrating/v2.0.0-pre11.md
|
|
@@ -190,6 +201,7 @@ files:
|
|
|
190
201
|
- docs/migrating/v2.0.0-pre14.md
|
|
191
202
|
- docs/migrating/v2.0.0-pre18.md
|
|
192
203
|
- docs/migrating/v2.0.0-pre19.md
|
|
204
|
+
- docs/migrating/v2.0.0-pre22.md
|
|
193
205
|
- docs/migrating/v2.0.0-pre5.md
|
|
194
206
|
- docs/migrating/v2.0.0-pre6.md
|
|
195
207
|
- docs/migrating/v2.0.0-pre7.md
|
|
@@ -204,6 +216,7 @@ files:
|
|
|
204
216
|
- examples/json_usage_patterns.rb
|
|
205
217
|
- examples/relationships.rb
|
|
206
218
|
- examples/safe_dump.rb
|
|
219
|
+
- examples/sampling_demo.rb
|
|
207
220
|
- examples/single_connection_transaction_confusions.rb
|
|
208
221
|
- familia.gemspec
|
|
209
222
|
- lib/familia.rb
|
|
@@ -255,11 +268,14 @@ files:
|
|
|
255
268
|
- lib/familia/features/relationships/collection_operations.rb
|
|
256
269
|
- lib/familia/features/relationships/indexing.rb
|
|
257
270
|
- lib/familia/features/relationships/indexing/multi_index_generators.rb
|
|
271
|
+
- lib/familia/features/relationships/indexing/rebuild_strategies.rb
|
|
258
272
|
- lib/familia/features/relationships/indexing/unique_index_generators.rb
|
|
259
273
|
- lib/familia/features/relationships/indexing_relationship.rb
|
|
260
274
|
- lib/familia/features/relationships/participation.rb
|
|
261
275
|
- lib/familia/features/relationships/participation/participant_methods.rb
|
|
276
|
+
- lib/familia/features/relationships/participation/rebuild_strategies.md
|
|
262
277
|
- lib/familia/features/relationships/participation/target_methods.rb
|
|
278
|
+
- lib/familia/features/relationships/participation_membership.rb
|
|
263
279
|
- lib/familia/features/relationships/participation_relationship.rb
|
|
264
280
|
- lib/familia/features/relationships/score_encoding.rb
|
|
265
281
|
- lib/familia/features/safe_dump.rb
|
|
@@ -279,6 +295,7 @@ files:
|
|
|
279
295
|
- lib/familia/horreum/settings.rb
|
|
280
296
|
- lib/familia/horreum/utils.rb
|
|
281
297
|
- lib/familia/identifier_extractor.rb
|
|
298
|
+
- lib/familia/instrumentation.rb
|
|
282
299
|
- lib/familia/json_serializer.rb
|
|
283
300
|
- lib/familia/logging.rb
|
|
284
301
|
- lib/familia/refinements.rb
|
|
@@ -287,9 +304,12 @@ files:
|
|
|
287
304
|
- lib/familia/refinements/time_literals.rb
|
|
288
305
|
- lib/familia/secure_identifier.rb
|
|
289
306
|
- lib/familia/settings.rb
|
|
307
|
+
- lib/familia/thread_safety/instrumented_mutex.rb
|
|
308
|
+
- lib/familia/thread_safety/monitor.rb
|
|
290
309
|
- lib/familia/utils.rb
|
|
291
310
|
- lib/familia/verifiable_identifier.rb
|
|
292
311
|
- lib/familia/version.rb
|
|
312
|
+
- lib/middleware/database_command_counter.rb
|
|
293
313
|
- lib/middleware/database_logger.rb
|
|
294
314
|
- lib/multi_result.rb
|
|
295
315
|
- pr_agent.toml
|
|
@@ -302,6 +322,8 @@ files:
|
|
|
302
322
|
- try/edge_cases/reserved_keywords_try.rb
|
|
303
323
|
- try/edge_cases/string_coercion_try.rb
|
|
304
324
|
- try/edge_cases/ttl_side_effects_try.rb
|
|
325
|
+
- try/features/count_any_edge_cases_try.rb
|
|
326
|
+
- try/features/count_any_methods_try.rb
|
|
305
327
|
- try/features/encrypted_fields/aad_protection_try.rb
|
|
306
328
|
- try/features/encrypted_fields/concealed_string_core_try.rb
|
|
307
329
|
- try/features/encrypted_fields/context_isolation_try.rb
|
|
@@ -337,11 +359,15 @@ files:
|
|
|
337
359
|
- try/features/quantization/quantization_try.rb
|
|
338
360
|
- try/features/real_feature_integration_try.rb
|
|
339
361
|
- try/features/relationships/indexing_commands_verification_try.rb
|
|
362
|
+
- try/features/relationships/indexing_rebuild_try.rb
|
|
340
363
|
- try/features/relationships/indexing_try.rb
|
|
364
|
+
- try/features/relationships/participation_bidirectional_try.rb
|
|
341
365
|
- try/features/relationships/participation_commands_verification_spec.rb
|
|
342
366
|
- try/features/relationships/participation_commands_verification_try.rb
|
|
343
367
|
- try/features/relationships/participation_performance_improvements_try.rb
|
|
344
368
|
- try/features/relationships/participation_reverse_index_try.rb
|
|
369
|
+
- try/features/relationships/participation_target_class_resolution_try.rb
|
|
370
|
+
- try/features/relationships/participation_unresolved_target_try.rb
|
|
345
371
|
- try/features/relationships/relationships_api_changes_try.rb
|
|
346
372
|
- try/features/relationships/relationships_edge_cases_try.rb
|
|
347
373
|
- try/features/relationships/relationships_performance_minimal_try.rb
|
|
@@ -384,10 +410,15 @@ files:
|
|
|
384
410
|
- try/integration/models/familia_object_try.rb
|
|
385
411
|
- try/integration/persistence_operations_try.rb
|
|
386
412
|
- try/integration/relationships_persistence_round_trip_try.rb
|
|
413
|
+
- try/integration/save_methods_consistency_try.rb
|
|
387
414
|
- try/integration/scenarios_try.rb
|
|
388
415
|
- try/integration/secure_identifier_try.rb
|
|
416
|
+
- try/integration/transaction_safety_core_try.rb
|
|
417
|
+
- try/integration/transaction_safety_workflow_try.rb
|
|
389
418
|
- try/integration/verifiable_identifier_try.rb
|
|
419
|
+
- try/investigation/pipeline_routing/README.md
|
|
390
420
|
- try/performance/benchmarks_try.rb
|
|
421
|
+
- try/performance/transaction_safety_benchmark_try.rb
|
|
391
422
|
- try/support/benchmarks/deserialization_benchmark.rb
|
|
392
423
|
- try/support/benchmarks/deserialization_correctness_test.rb
|
|
393
424
|
- try/support/debugging/README.md
|
|
@@ -437,6 +468,18 @@ files:
|
|
|
437
468
|
- try/support/prototypes/pooling/lib/visualize_stress_results.rb
|
|
438
469
|
- try/support/prototypes/pooling/pool_siege.rb
|
|
439
470
|
- try/support/prototypes/pooling/run_stress_tests.rb
|
|
471
|
+
- try/thread_safety/README.md
|
|
472
|
+
- try/thread_safety/class_connection_chain_race_try.rb
|
|
473
|
+
- try/thread_safety/connection_chain_race_try.rb
|
|
474
|
+
- try/thread_safety/encryption_manager_cache_race_try.rb
|
|
475
|
+
- try/thread_safety/feature_registry_race_try.rb
|
|
476
|
+
- try/thread_safety/fiber_pipeline_isolation_try.rb
|
|
477
|
+
- try/thread_safety/fiber_transaction_isolation_try.rb
|
|
478
|
+
- try/thread_safety/field_registration_race_try.rb
|
|
479
|
+
- try/thread_safety/logger_initialization_race_try.rb
|
|
480
|
+
- try/thread_safety/middleware_registration_race_try.rb
|
|
481
|
+
- try/thread_safety/module_config_race_try.rb
|
|
482
|
+
- try/thread_safety/secure_identifier_cache_race_try.rb
|
|
440
483
|
- try/unit/core/autoloader_try.rb
|
|
441
484
|
- try/unit/core/base_enhancements_try.rb
|
|
442
485
|
- try/unit/core/connection_try.rb
|
|
@@ -444,6 +487,9 @@ files:
|
|
|
444
487
|
- try/unit/core/extensions_try.rb
|
|
445
488
|
- try/unit/core/familia_logger_try.rb
|
|
446
489
|
- try/unit/core/familia_try.rb
|
|
490
|
+
- try/unit/core/middleware_sampling_try.rb
|
|
491
|
+
- try/unit/core/middleware_test_helpers_bug_try.rb
|
|
492
|
+
- try/unit/core/middleware_thread_safety_try.rb
|
|
447
493
|
- try/unit/core/middleware_try.rb
|
|
448
494
|
- try/unit/core/settings_try.rb
|
|
449
495
|
- try/unit/core/time_utils_try.rb
|
|
@@ -455,10 +501,12 @@ files:
|
|
|
455
501
|
- try/unit/data_types/hash_try.rb
|
|
456
502
|
- try/unit/data_types/list_try.rb
|
|
457
503
|
- try/unit/data_types/lock_try.rb
|
|
504
|
+
- try/unit/data_types/serialization_try.rb
|
|
458
505
|
- try/unit/data_types/sorted_set_try.rb
|
|
459
506
|
- try/unit/data_types/sorted_set_zadd_options_try.rb
|
|
460
507
|
- try/unit/data_types/string_try.rb
|
|
461
508
|
- try/unit/data_types/unsortedset_try.rb
|
|
509
|
+
- try/unit/familia_resolve_class_try.rb
|
|
462
510
|
- try/unit/horreum/auto_indexing_on_save_try.rb
|
|
463
511
|
- try/unit/horreum/automatic_index_validation_try.rb
|
|
464
512
|
- try/unit/horreum/base_try.rb
|
|
@@ -471,16 +519,20 @@ files:
|
|
|
471
519
|
- try/unit/horreum/field_definition_try.rb
|
|
472
520
|
- try/unit/horreum/initialization_try.rb
|
|
473
521
|
- try/unit/horreum/json_type_preservation_try.rb
|
|
522
|
+
- try/unit/horreum/optimized_loading_try.rb
|
|
474
523
|
- try/unit/horreum/relations_try.rb
|
|
475
524
|
- try/unit/horreum/serialization_persistent_fields_try.rb
|
|
476
525
|
- try/unit/horreum/serialization_try.rb
|
|
477
526
|
- try/unit/horreum/settings_try.rb
|
|
478
527
|
- try/unit/horreum/unique_index_edge_cases_try.rb
|
|
479
528
|
- try/unit/horreum/unique_index_guard_validation_try.rb
|
|
529
|
+
- try/unit/middleware/database_command_counter_methods_try.rb
|
|
530
|
+
- try/unit/middleware/database_logger_methods_try.rb
|
|
480
531
|
- try/unit/refinements/dear_json_array_methods_try.rb
|
|
481
532
|
- try/unit/refinements/dear_json_hash_methods_try.rb
|
|
482
533
|
- try/unit/refinements/time_literals_numeric_methods_try.rb
|
|
483
534
|
- try/unit/refinements/time_literals_string_methods_try.rb
|
|
535
|
+
- try/unit/thread_safety_monitor_try.rb
|
|
484
536
|
- try/valkey.conf
|
|
485
537
|
homepage: https://github.com/delano/familia
|
|
486
538
|
licenses:
|
|
@@ -494,14 +546,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
494
546
|
requirements:
|
|
495
547
|
- - ">="
|
|
496
548
|
- !ruby/object:Gem::Version
|
|
497
|
-
version:
|
|
549
|
+
version: 3.3.6
|
|
498
550
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
499
551
|
requirements:
|
|
500
552
|
- - ">="
|
|
501
553
|
- !ruby/object:Gem::Version
|
|
502
554
|
version: '0'
|
|
503
555
|
requirements: []
|
|
504
|
-
rubygems_version: 3.
|
|
556
|
+
rubygems_version: 3.7.2
|
|
505
557
|
specification_version: 4
|
|
506
558
|
summary: An ORM for Valkey-compatible databases in Ruby.
|
|
507
559
|
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
|
-
..
|