-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: initial upgrading instructions
- Loading branch information
Showing
1 changed file
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
# Upgrade Guide | ||
|
||
This document describes the breaking changes introduced in each major version of MyLibraryJS and the necessary steps you need to take to ensure your application continues to work correctly. | ||
|
||
## Upgrading from 2.x to 3.x | ||
|
||
### Migrating from `TaskExecutor` to `GolemNetwork` | ||
|
||
Since the `TaskExecutor` has been removed in this release, you can migrate to the [@golem-sdk/task-executor](https://www.npmjs.com/package/@golem-sdk/task-executor) package as `1.x` of that package is compatible with `[email protected]`. | ||
|
||
If you wish to stick to `golem-js`, here are the examples of changes which you need to make: | ||
|
||
#### Simple, single-command use cases | ||
|
||
Areas where the changes are needed: | ||
|
||
- You stop using `TaskExecutor` and switch to `GolemNetwork` instead. | ||
- Be explicit about the expected computation time and pricing strategy so that `golem-js` can estimate the budget. | ||
- You reach for an exe-unit representation with the `ResourceRental.getExeUnit` method and call your commands via the provided `ExeUnit` instance. | ||
|
||
**Before:** | ||
|
||
```ts | ||
// before | ||
import { TaskExecutor } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const executor = await TaskExecutor.create("golem/alpine:latest"); | ||
try { | ||
await executor.run(async (ctx) => console.log((await ctx.run("echo 'Hello World'")).stdout)); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await executor.shutdown(); | ||
} | ||
})(); | ||
``` | ||
|
||
**After:** | ||
|
||
```ts | ||
// after | ||
import { GolemNetwork } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const glm = new GolemNetwork(); | ||
try { | ||
await glm.connect(); | ||
|
||
const retnal = await glm.oneOf({ | ||
order: { | ||
demand: { | ||
workload: { imageTag: "golem/alpine:latest" }, | ||
}, | ||
// You have to be now explicit about about your terms and expectatios from the market | ||
market: { | ||
rentHours: 5 / 60, | ||
pricing: { | ||
model: "linear", | ||
maxStartPrice: 0.5, | ||
maxCpuPerHourPrice: 1.0, | ||
maxEnvPerHourPrice: 0.5, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
// You will work with exe-unit objects instead of "executor" | ||
await rental | ||
.getExeUnit() | ||
.then((exe) => exe.run("echo 'Hello World'")) | ||
.then((res) => console.log(res.stdout)); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await glm.disconnect(); | ||
} | ||
})(); | ||
``` | ||
|
||
#### Repeating commands with `map` of different parameter values | ||
|
||
Areas where the changes are needed: | ||
|
||
- Instead of referring the `TaskExecutor` instance in the `map` function, you need to switch to the `ExeUnit` instance provided by the `ResourceRental` | ||
|
||
**Before:** | ||
|
||
```ts | ||
// before | ||
import { GolemNetwork } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const executor = await GolemNetwork.create("golem/alpine:latest"); | ||
try { | ||
const inputs = [1, 2, 3, 4, 5]; | ||
|
||
const results = await Promise.allSettled( | ||
inputs.map((input) => executor.run((ctx) => ctx.run(`echo 'Hello ${input}`))), | ||
); | ||
|
||
const responses = results.map((p) => (p.status === "fulfilled" ? p.value.stdout : null)).filter((v) => v !== null); | ||
|
||
console.log(responses); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await executor.shutdown(); | ||
} | ||
})(); | ||
``` | ||
|
||
```ts | ||
// after | ||
import { GolemNetwork } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const glm = new GolemNetwork(); | ||
try { | ||
await glm.connect(); | ||
|
||
const retnal = await glm.oneOf({ | ||
order: { | ||
demand: { | ||
workload: { imageTag: "golem/alpine:latest" }, | ||
}, | ||
// You have to be now explicit about about your terms and expectatios from the market | ||
market: { | ||
rentHours: 5 / 60, | ||
pricing: { | ||
model: "linear", | ||
maxStartPrice: 0.5, | ||
maxCpuPerHourPrice: 1.0, | ||
maxEnvPerHourPrice: 0.5, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
const inputs = [1, 2, 3, 4, 5]; | ||
|
||
const exe = await rental.getExeUnit(); | ||
|
||
// You still take the necessary precaucions, pipeline your work and processing | ||
const results = await Promise.allSettled( | ||
inputs.map((input) => exe.run(`echo 'Hello ${input}`).then((res) => res.stdout)), | ||
); | ||
|
||
// You still filter for the values which succeeded | ||
const responses = results.map((p) => (p.status === "fulfilled" ? p.value : null)).filter((v) => v !== null); | ||
|
||
console.log(responses); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await glm.disconnect(); | ||
} | ||
})(); | ||
``` | ||
|
||
#### Engaging with many providers at the same time | ||
|
||
Areas where the changes are needed: | ||
|
||
- instead of using `maxParallelTasks` from `TaskExecutor`, use `concurrency` option on `GolemNetwork.manyOf` market order spec argument. | ||
|
||
**Before:** | ||
|
||
```ts | ||
// before | ||
import { GolemNetwork } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const executor = await GolemNetwork.create({ | ||
imageTag: "golem/alpine:latest", | ||
// π’ Number of max providers which you want to engage with | ||
maxParallelTasks: 3, | ||
}); | ||
|
||
try { | ||
const inputs = [1, 2, 3, 4, 5]; | ||
|
||
const results = await Promise.allSettled( | ||
inputs.map((input) => executor.run((ctx) => ctx.run(`echo 'Hello ${input}`))), | ||
); | ||
|
||
const responses = results.map((p) => (p.status === "fulfilled" ? p.value.stdout : null)).filter((v) => v !== null); | ||
|
||
console.log(responses); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await executor.shutdown(); | ||
} | ||
})(); | ||
``` | ||
|
||
```ts | ||
// after | ||
import { GolemNetwork } from "@golem-sdk/golem-js"; | ||
|
||
(async function main() { | ||
const glm = new GolemNetwork(); | ||
try { | ||
await glm.connect(); | ||
|
||
// π You acquire a pool of ResourceRentals | ||
const pool = await glm.manyOf({ | ||
// π’ Number of max providers which you want to engage with | ||
concurrency: 3, | ||
order: { | ||
demand: { | ||
workload: { imageTag: "golem/alpine:latest" }, | ||
}, | ||
// You have to be now explicit about about your terms and expectatios from the market | ||
market: { | ||
rentHours: 5 / 60, | ||
pricing: { | ||
model: "linear", | ||
maxStartPrice: 0.5, | ||
maxCpuPerHourPrice: 1.0, | ||
maxEnvPerHourPrice: 0.5, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
const inputs = [1, 2, 3, 4, 5]; | ||
|
||
// You still take the necessary precaucions, pipeline your work and processing | ||
const results = await Promise.allSettled( | ||
inputs.map((input) => | ||
// ππ You access rentals from the pool | ||
pool.withRental((rental) => | ||
rental | ||
// πππ You issue the comands as in case of a single-provider scenario | ||
.getExeUnit() | ||
.run(`echo 'Hello ${input}`) | ||
.then((res) => res.stdout), | ||
), | ||
), | ||
); | ||
|
||
// You still filter for the values which succeeded | ||
const responses = results.map((p) => (p.status === "fulfilled" ? p.value : null)).filter((v) => v !== null); | ||
|
||
console.log(responses); | ||
} catch (error) { | ||
console.error("Failed to execute work:", error); | ||
} finally { | ||
await glm.disconnect(); | ||
} | ||
})(); | ||
``` |