Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions examples/go/warm_pools/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"context"
"log"

"github.com/daytona/clients/sdk-go/pkg/daytona"
"github.com/daytona/clients/sdk-go/pkg/types"
)

func main() {
// Create a new Daytona client using environment variables.
// Set DAYTONA_API_KEY before running.
client, err := daytona.NewClient()
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}

ctx := context.Background()

// Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
// Target is optional and defaults to the organization default region.
pool, err := client.WarmPool.Create(ctx, &types.CreateWarmPoolParams{
Snapshot: "my-snapshot",
Pool: 3,
})
if err != nil {
log.Fatalf("Failed to create warm pool: %v", err)
}
log.Printf("✓ Created warm pool %s for snapshot %q in %s\n", pool.ID, pool.Snapshot, pool.Target)

// List warm pools. CurrentSize vs Pool is the status check: CurrentSize is the
// number of ready sandboxes; ErrorReason is set when the pool cannot be filled.
pools, err := client.WarmPool.List(ctx)
if err != nil {
log.Fatalf("Failed to list warm pools: %v", err)
}
for _, p := range pools {
status := ""
if p.ErrorReason != nil {
status = " (error: " + *p.ErrorReason + ")"
}
log.Printf("%s (%s): %d/%d ready%s\n", p.Snapshot, p.Target, p.CurrentSize, p.Pool, status)
}

// Grow the pool. Setting the size to 0 drains it without deleting the pool.
updated, err := client.WarmPool.Update(ctx, pool.ID, 5)
if err != nil {
log.Fatalf("Failed to update warm pool: %v", err)
}
log.Printf("✓ Updated desired size to %d\n", updated.Pool)

// Cleanup
if err := client.WarmPool.Delete(ctx, pool.ID); err != nil {
log.Fatalf("Failed to delete warm pool: %v", err)
}
log.Println("✓ Deleted warm pool")
}
24 changes: 24 additions & 0 deletions examples/java/warm-pools/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
application
}

group = "io.daytona.examples"
version = "0.1.0"

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation("io.daytona:sdk-java")
}

application {
mainClass.set("io.daytona.examples.WarmPools")
}
14 changes: 14 additions & 0 deletions examples/java/warm-pools/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
rootProject.name = "warm-pools"

dependencyResolutionManagement {
repositories {
mavenLocal()
mavenCentral()
}
}

includeBuild("../../../sdk-java") {
dependencySubstitution {
substitute(module("io.daytona:sdk-java")).using(project(":"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.daytona.examples;

import io.daytona.sdk.Daytona;
import io.daytona.sdk.model.WarmPool;

public class WarmPools {
public static void main(String[] args) {
try (Daytona daytona = new Daytona()) {
// Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
// The target (third argument) is optional; null means the organization default region.
WarmPool pool = daytona.warmPool().create("my-snapshot", 3, null);
System.out.println("Created warm pool " + pool.getId()
+ " for snapshot '" + pool.getSnapshot() + "' in " + pool.getTarget());

// List warm pools. currentSize vs pool is the status check: currentSize is the
// number of ready sandboxes; errorReason is set when the pool cannot be filled.
for (WarmPool p : daytona.warmPool().list()) {
String status = p.getErrorReason() != null ? " (error: " + p.getErrorReason() + ")" : "";
System.out.println(p.getSnapshot() + " (" + p.getTarget() + "): "
+ p.getCurrentSize() + "/" + p.getPool() + " ready" + status);
}

// Grow the pool. Setting the size to 0 drains it without deleting the pool.
WarmPool updated = daytona.warmPool().update(pool.getId(), 5);
System.out.println("Updated desired size to " + updated.getPool());

// Cleanup
daytona.warmPool().delete(pool.getId());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Cleanup on line 28 is not guaranteed if a prior operation throws. Wrap the body in try/finally so delete still runs on failure — the Lifecycle example demonstrates this pattern.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/java/warm-pools/src/main/java/io/daytona/examples/WarmPools.java, line 28:

<comment>Cleanup on line 28 is not guaranteed if a prior operation throws. Wrap the body in try/finally so delete still runs on failure — the Lifecycle example demonstrates this pattern.</comment>

<file context>
@@ -0,0 +1,32 @@
+            System.out.println("Updated desired size to " + updated.getPool());
+
+            // Cleanup
+            daytona.warmPool().delete(pool.getId());
+            System.out.println("Deleted warm pool");
+        }
</file context>

System.out.println("Deleted warm pool");
}
}
}
29 changes: 29 additions & 0 deletions examples/python/warm-pools/_async/warm_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import asyncio

from daytona import AsyncDaytona


async def main():
async with AsyncDaytona() as daytona:
# Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
# `target` is optional and defaults to the organization default region.
pool = await daytona.warm_pool.create("my-snapshot", pool=3)
print(f"Created warm pool {pool.id} for snapshot '{pool.snapshot}' in {pool.target}")

# List warm pools. current_size vs pool is the status check: current_size is the
# number of ready sandboxes; error_reason is set when the pool cannot be filled.
for p in await daytona.warm_pool.list():
status = f" (error: {p.error_reason})" if p.error_reason else ""
print(f"{p.snapshot} ({p.target}): {p.current_size}/{p.pool} ready{status}")

# Grow the pool. Setting pool to 0 drains it without deleting the pool.
updated = await daytona.warm_pool.update(pool.id, pool=5)
print(f"Updated desired size to {updated.pool}")

# Cleanup
await daytona.warm_pool.delete(pool.id)
print("Deleted warm pool")


if __name__ == "__main__":
asyncio.run(main())
28 changes: 28 additions & 0 deletions examples/python/warm-pools/warm_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from daytona import Daytona


def main():
daytona = Daytona()

# Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
# `target` is optional and defaults to the organization default region.
pool = daytona.warm_pool.create("my-snapshot", pool=3)
print(f"Created warm pool {pool.id} for snapshot '{pool.snapshot}' in {pool.target}")

# List warm pools. current_size vs pool is the status check: current_size is the
# number of ready sandboxes; error_reason is set when the pool cannot be filled.
for p in daytona.warm_pool.list():
status = f" (error: {p.error_reason})" if p.error_reason else ""
print(f"{p.snapshot} ({p.target}): {p.current_size}/{p.pool} ready{status}")

# Grow the pool. Setting pool to 0 drains it without deleting the pool.
updated = daytona.warm_pool.update(pool.id, pool=5)
print(f"Updated desired size to {updated.pool}")

# Cleanup
daytona.warm_pool.delete(pool.id)
print("Deleted warm pool")


if __name__ == "__main__":
main()
25 changes: 25 additions & 0 deletions examples/ruby/warm-pools/warm_pool.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require 'daytona'

daytona = Daytona::Daytona.new

# Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
# `target` is optional and defaults to the organization default region.
pool = daytona.warm_pool.create('my-snapshot', 3)
puts "Created warm pool #{pool.id} for snapshot '#{pool.snapshot}' in #{pool.target}"

# List warm pools. current_size vs pool is the status check: current_size is the
# number of ready sandboxes; error_reason is set when the pool cannot be filled.
daytona.warm_pool.list.each do |p|
status = p.error_reason ? " (error: #{p.error_reason})" : ''
puts "#{p.snapshot} (#{p.target}): #{p.current_size}/#{p.pool} ready#{status}"
end

# Grow the pool. Setting the size to 0 drains it without deleting the pool.
updated = daytona.warm_pool.update(pool.id, 5)
puts "Updated desired size to #{updated.pool}"

# Cleanup
daytona.warm_pool.delete(pool.id)
puts 'Deleted warm pool'
28 changes: 28 additions & 0 deletions examples/typescript/warm-pools/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Daytona } from '@daytona/sdk'

async function main() {
const daytona = new Daytona()

// Create a warm pool that keeps ready-to-use sandboxes for an existing snapshot.
// `target` is optional and defaults to the organization default region.
const pool = await daytona.warmPool.create({ snapshot: 'my-snapshot', pool: 3 })
console.log(`Created warm pool ${pool.id} for snapshot '${pool.snapshot}' in ${pool.target}`)

// List warm pools. currentSize vs pool is the status check: currentSize is the
// number of ready sandboxes; errorReason is set when the pool cannot be filled.
const pools = await daytona.warmPool.list()
for (const p of pools) {
const status = p.errorReason ? ` (error: ${p.errorReason})` : ''
console.log(`${p.snapshot} (${p.target}): ${p.currentSize}/${p.pool} ready${status}`)
}

// Grow the pool. Setting pool to 0 drains it without deleting the pool.
const updated = await daytona.warmPool.update(pool.id, { pool: 5 })
console.log(`Updated desired size to ${updated.pool}`)

// Cleanup
await daytona.warmPool.delete(pool.id)
console.log('Deleted warm pool')
}

main()
4 changes: 4 additions & 0 deletions sdk-go/pkg/daytona/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ type Client struct {

// Secret provides methods for managing organization secrets.
Secret *SecretService

// WarmPool provides methods for managing warm pools of ready sandboxes.
WarmPool *WarmPoolService
}

// NewClient creates a new Daytona client with default configuration.
Expand Down Expand Up @@ -272,6 +275,7 @@ func NewClientWithConfig(config *types.DaytonaConfig) (*Client, error) {
client.Volume = NewVolumeService(client)
client.Snapshot = NewSnapshotService(client)
client.Secret = NewSecretService(client)
client.WarmPool = NewWarmPoolService(client)
client.subscriptionManager = common.NewEventSubscriptionManager(nil)

token := client.apiKey
Expand Down
1 change: 1 addition & 0 deletions sdk-go/pkg/daytona/volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func createTestClientWithServer(t *testing.T, server *httptest.Server) *Client {
client.Volume = NewVolumeService(client)
client.Snapshot = NewSnapshotService(client)
client.Secret = NewSecretService(client)
client.WarmPool = NewWarmPoolService(client)

return client
}
Expand Down
Loading
Loading