Files
osiris/MULTI_INSTANCE.md
Timur Gordon 097360ad12 first commit
2025-10-20 22:24:25 +02:00

8.1 KiB

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

// 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

// 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

// 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

// 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

// 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

// 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

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.

let name = instance.name();
print(`Instance: ${name}`);

put_note(note)

Store a note in this instance.

let id = instance.put_note(note);

Returns: Note ID (string)

get_note(namespace, id)

Retrieve a note from this instance.

let note = instance.get_note("notes", id);

Returns: Note object

put_event(event)

Store an event in this instance.

let id = instance.put_event(event);

Returns: Event ID (string)

get_event(namespace, id)

Retrieve an event from this instance.

let event = instance.get_event("calendar", id);

Returns: Event object

query(namespace, field, value)

Query by indexed field in this instance.

let ids = instance.query("notes", "title", "My Note");

Returns: Array of IDs

delete_note(note)

Delete a note from this instance.

let deleted = instance.delete_note(note);

Returns: Boolean (true if deleted)

delete_event(event)

Delete an event from this instance.

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<GenericStore>        │
│   - runtime: Arc<Runtime>           │
└────┬───────────────────┬────────────┘
     │                   │
┌────▼──────────┐   ┌───▼───────────┐
│  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

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

// 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

// 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

// 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

// 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