Skip to content

Conversation

@speeddragon
Copy link

@speeddragon speeddragon commented Oct 16, 2025

Before Merge

Description

This PR adds S3 support to hb_store.

  • This is under the s3 profile.
  • Required keys are:
    • bucket
    • priv_access_key_id
    • priv_secret_access_key
  • Optional keys are:
    • region
    • endpoint
    • force_path_style
    • retry-attempts
    • min-retry-delay
    • max-retry-delay
    • retry-mode
    • scope
  • Added MinIO via docker-compose to test S3 behaviour.
  • 2 new dependencies added:
    • erlcloud_s3 dependency added to interface with S3 protocol.
    • meck dependency added to test error behaviour from erlcloud_s3.

Store Configuration

To test this store, create the config.flat file and ensure the MinIO service is running.

store/ao-types: .=list

% S3 Config
store/1/ao-types: store-module=atom
store/1/store-module: hb_store_s3
store/1/bucket: hb-s3
store/1/priv_access_key_id: minioadmin
store/1/priv_secret_access_key: minioadmin
store/1/endpoint: http://localhost:9000
store/1/force_path_style: true
store/1/region: us-east-1

% Gateway with S3 Config
store/2/ao-types: store-module=atom
store/2/store-module: hb_store_gateway
store/2/remote-store/ao-types: .=list
store/2/remote-store/1/ao-types: store-module=atom
store/2/remote-store/1/store-module: hb_store_s3
store/2/remote-store/1/bucket: hb-s3
store/2/remote-store/1/priv_access_key_id: minioadmin
store/2/remote-store/1/priv_secret_access_key: minioadmin
store/2/remote-store/1/endpoint: http://localhost:9000
store/2/remote-store/1/force_path_style: true
store/2/remote-store/1/region: us-east-1

A configuration with LMDB as the first store would be:

store/ao-types: .=list

% LMDB
store/1/ao-types: store-module=atom
store/1/store-module: hb_store_lmdb
store/1/name: cache-mainnet/lmdb

% S3 Config
store/2/ao-types: store-module=atom
store/2/store-module: hb_store_s3
store/2/bucket: hb-s3
store/2/priv_access_key_id: minioadmin
store/2/priv_secret_access_key: minioadmin
store/2/endpoint: http://localhost:9000
store/2/force_path_style: true
store/2/region: us-east-1

% Gateway with S3 Config
store/3/ao-types: store-module=atom
store/3/store-module: hb_store_gateway
store/3/local-store/ao-types: .=list
store/3/local-store/1/ao-types: store-module=atom
store/3/local-store/1/store-module: hb_store_s3
store/3/local-store/1/bucket: hb-s3
store/3/local-store/1/priv_access_key_id: minioadmin
store/3/local-store/1/priv_secret_access_key: minioadmin
store/3/local-store/1/endpoint: http://localhost:9000
store/3/local-store/1/force_path_style: true
store/3/local-store/1/region: us-east-1

Decisions

  • Sharded key on the first key element. Keys with a size equal to or below SHARD_CUT (currently set to 4) aren't valid.

Performance

Storing a message in S3 using one file per message attributes make storing a complete message quite slow.

hb_store: -generate_test_suite/2-fun-1- (hb_store_s3: benchmark message read write)...
        Generated 25 messages (size 8,192 bits)... 
        Wrote 25 messages in 3,103ms (8 messages/s)... 
        Read 25 messages in 4,580ms (5 messages/s)... [8.138 s] ok

Future work

  • Extract exponential backoff from hb_store_s3 to hb_store.

@speeddragon speeddragon force-pushed the speeddragon/s3_store_new branch from f51380e to e50f2cb Compare October 22, 2025 17:42
generate_test_suite(Suite, test_stores()).
generate_test_suite(Suite, Stores) ->
hb:init(),
application:ensure_all_started(hb),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary to use hb_http_client in hb_store_s3 requests.

@speeddragon speeddragon force-pushed the speeddragon/s3_store_new branch from 86b457a to 2904833 Compare November 3, 2025 15:51
@speeddragon speeddragon changed the title Support Store S3 feat: Support Store S3 Nov 6, 2025
@speeddragon speeddragon force-pushed the speeddragon/s3_store_new branch 3 times, most recently from bb6a3e6 to 5054c60 Compare November 14, 2025 16:03
@speeddragon speeddragon force-pushed the speeddragon/s3_store_new branch from 5054c60 to 4712906 Compare November 21, 2025 15:32
shyba and others added 7 commits January 28, 2026 20:06
Initial implementation of hb_store_s3 module providing S3-compatible
storage support via erlcloud. Implements standard store interface
with read, write, list, and resolve operations.
fixed duplicate reads and writes
Integrate hb_store_s3 into hb_cache and hb_store test suites.
Fix link resolution and reset functionality for S3 compatibility.
Skip match tests for S3 store (not supported).
Remove hackney dependency in favor of gun for S3 operations.
Improve error handling, add function documentation, and clean up
code style throughout the S3 store module.
Remove link and group abstractions from S3 store in favor of
direct key-value operations. Fix boolean type handling (use binary
instead of boolean ao-type). Fix HTTP request handling and cache bugs.
Add configurable sharding for S3 keys to distribute data across
prefixes. Fix shard_key generation and path resolution with sharding.
Ensure module compiles correctly without S3 profile.
Add erlcloud to release dependencies under S3 profile.
Remove unused functions, improve write retry behavior,
and clean up minor code style issues.
@nikooo777 nikooo777 force-pushed the speeddragon/s3_store_new branch from 4712906 to db9b0d7 Compare January 28, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants