# OSIRIS Multi-Instance Support โœ… OSIRIS now supports multiple instances in a single Rhai script, allowing you to work with different HeroDB databases simultaneously. ## ๐ŸŽ‰ Status: FULLY OPERATIONAL ``` โœ… OsirisInstance type created โœ… Dynamic instance creation โœ… Independent storage per instance โœ… Same note/event in multiple instances โœ… Test script working ``` ## ๐Ÿš€ Quick Start ### Create Multiple Instances ```rhai // Create two OSIRIS instances pointing to different databases let freezone = osiris("freezone", "redis://localhost:6379", 1); let my_osiris = osiris("my_osiris", "redis://localhost:6379", 2); // Create a note let my_note = note("notes") .title("Shared Note") .content("This will be stored in both instances"); // Store in both instances let id1 = freezone.put_note(my_note); let id2 = my_osiris.put_note(my_note); ``` ## ๐Ÿ“ Complete Example ```rhai // Multi-Instance OSIRIS Example print("Creating OSIRIS instances..."); let freezone = osiris("freezone", "redis://localhost:6379", 1); let my_osiris = osiris("my_osiris", "redis://localhost:6379", 2); print(`Created: ${freezone.name()}`); print(`Created: ${my_osiris.name()}`); // Create a note let my_note = note("shared_notes") .title("Multi-Instance Test") .content("Stored in multiple OSIRIS instances") .tag("shared", "true"); // Store in freezone let freezone_id = freezone.put_note(my_note); print(`Stored in freezone: ${freezone_id}`); // Store in my_osiris let my_id = my_osiris.put_note(my_note); print(`Stored in my_osiris: ${my_id}`); // Retrieve from each let note1 = freezone.get_note("shared_notes", freezone_id); let note2 = my_osiris.get_note("shared_notes", my_id); // Query each instance let ids1 = freezone.query("shared_notes", "tags:tag", "shared=true"); let ids2 = my_osiris.query("shared_notes", "tags:tag", "shared=true"); ``` ## ๐ŸŽฏ Use Cases ### 1. **Multi-Tenant Systems** ```rhai // Each tenant has their own OSIRIS instance let tenant1 = osiris("tenant1", "redis://localhost:6379", 1); let tenant2 = osiris("tenant2", "redis://localhost:6379", 2); // Store tenant-specific data tenant1.put_note(tenant1_note); tenant2.put_note(tenant2_note); ``` ### 2. **Data Replication** ```rhai // Primary and backup instances let primary = osiris("primary", "redis://primary:6379", 1); let backup = osiris("backup", "redis://backup:6379", 1); // Store in both primary.put_note(note); backup.put_note(note); ``` ### 3. **Environment Separation** ```rhai // Development and production let dev = osiris("dev", "redis://dev:6379", 1); let prod = osiris("prod", "redis://prod:6379", 1); // Test in dev first dev.put_note(test_note); // Then promote to prod prod.put_note(test_note); ``` ### 4. **Cross-Database Operations** ```rhai // Different databases for different data types let notes_db = osiris("notes", "redis://localhost:6379", 1); let events_db = osiris("events", "redis://localhost:6379", 2); notes_db.put_note(note); events_db.put_event(event); ``` ## ๐Ÿ“š API Reference ### Creating an Instance ```rhai let instance = osiris(name, url, db_id); ``` **Parameters:** - `name` (string) - Instance name for identification - `url` (string) - HeroDB connection URL - `db_id` (int) - Database ID (0-15 typically) **Returns:** `OsirisInstance` ### Instance Methods #### `name()` Get the instance name. ```rhai let name = instance.name(); print(`Instance: ${name}`); ``` #### `put_note(note)` Store a note in this instance. ```rhai let id = instance.put_note(note); ``` **Returns:** Note ID (string) #### `get_note(namespace, id)` Retrieve a note from this instance. ```rhai let note = instance.get_note("notes", id); ``` **Returns:** Note object #### `put_event(event)` Store an event in this instance. ```rhai let id = instance.put_event(event); ``` **Returns:** Event ID (string) #### `get_event(namespace, id)` Retrieve an event from this instance. ```rhai let event = instance.get_event("calendar", id); ``` **Returns:** Event object #### `query(namespace, field, value)` Query by indexed field in this instance. ```rhai let ids = instance.query("notes", "title", "My Note"); ``` **Returns:** Array of IDs #### `delete_note(note)` Delete a note from this instance. ```rhai let deleted = instance.delete_note(note); ``` **Returns:** Boolean (true if deleted) #### `delete_event(event)` Delete an event from this instance. ```rhai let deleted = instance.delete_event(event); ``` **Returns:** Boolean (true if deleted) ## ๐Ÿ—๏ธ Architecture ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Rhai Script โ”‚ โ”‚ let freezone = osiris(...); โ”‚ โ”‚ let my_osiris = osiris(...); โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ OsirisInstance (Clone) โ”‚ โ”‚ - name: String โ”‚ โ”‚ - store: Arc โ”‚ โ”‚ - runtime: Arc โ”‚ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ HeroDB DB 1 โ”‚ โ”‚ HeroDB DB 2 โ”‚ โ”‚ (freezone) โ”‚ โ”‚ (my_osiris) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ## โœจ Features ### 1. **Independent Storage** Each instance maintains its own storage, indexes, and namespaces. ### 2. **Shared Objects** The same note or event object can be stored in multiple instances. ### 3. **Clone-Safe** Instances are cloneable and can be passed around in scripts. ### 4. **Error Isolation** Errors in one instance don't affect others. ### 5. **Named Instances** Each instance has a name for easy identification in logs and errors. ## ๐Ÿงช Testing ### Run the Multi-Instance Test ```bash cargo run --bin runner --features rhai-support -- test1 --script-file scripts/multi_instance.rhai ``` ### Expected Output ``` === Multi-Instance OSIRIS Test === Creating OSIRIS instances... โœ“ Created: freezone โœ“ Created: my_osiris Creating note... Note created: Multi-Instance Test Note Storing in freezone... โœ“ Stored in freezone with ID: c274731c-678d-4f3e-bc4a-22eb70dae698 Storing in my_osiris... โœ“ Stored in my_osiris with ID: c274731c-678d-4f3e-bc4a-22eb70dae698 Retrieving from freezone... โœ“ Retrieved from freezone: Multi-Instance Test Note Retrieving from my_osiris... โœ“ Retrieved from my_osiris: Multi-Instance Test Note Querying freezone... โœ“ Found in freezone: - c274731c-678d-4f3e-bc4a-22eb70dae698 Querying my_osiris... โœ“ Found in my_osiris: - c274731c-678d-4f3e-bc4a-22eb70dae698 === Test Complete === โœ… Script completed successfully! ``` ## ๐Ÿ’ก Best Practices ### 1. **Use Descriptive Names** ```rhai // Good let production = osiris("production", url, 1); let staging = osiris("staging", url, 2); // Less clear let db1 = osiris("db1", url, 1); let db2 = osiris("db2", url, 2); ``` ### 2. **Centralize Instance Creation** ```rhai // Create all instances at the start let freezone = osiris("freezone", "redis://localhost:6379", 1); let my_osiris = osiris("my_osiris", "redis://localhost:6379", 2); // Then use them throughout the script freezone.put_note(note1); my_osiris.put_note(note2); ``` ### 3. **Handle Errors Per Instance** ```rhai // Each instance can fail independently try { freezone.put_note(note); } catch (e) { print(`Freezone error: ${e}`); } try { my_osiris.put_note(note); } catch (e) { print(`My OSIRIS error: ${e}`); } ``` ### 4. **Use Different Databases** ```rhai // Separate databases for isolation let instance1 = osiris("inst1", "redis://localhost:6379", 1); let instance2 = osiris("inst2", "redis://localhost:6379", 2); ``` ## ๐ŸŽ‰ Success! Multi-instance OSIRIS support is **fully operational** and ready for: - โœ… Multi-tenant applications - โœ… Data replication - โœ… Environment separation - โœ… Cross-database operations - โœ… Production use