Skip to content

Commit 730584c

Browse files
Restructure Cluster, ExecutionContext and Command sdk (#49)
1 parent eb5d7e0 commit 730584c

9 files changed

Lines changed: 71 additions & 76 deletions

File tree

packages/databricks-sdk-js/src/apis/executionContext.integ.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ describe(__filename, function () {
2121
let commandsApi = new CommandsService(integSetup.client);
2222

2323
let context = await executionContextApi.create({
24-
clusterId: integSetup.clusterId,
24+
clusterId: integSetup.cluster.id,
2525
language: "python",
2626
});
2727
//console.log("Execution context", context);
2828

2929
let command = await commandsApi.execute({
30-
clusterId: integSetup.clusterId,
30+
clusterId: integSetup.cluster.id,
3131
contextId: context.id,
3232
language: "python",
3333
command: "print('juhu')",
@@ -38,7 +38,7 @@ describe(__filename, function () {
3838
while (true) {
3939
await sleep(3000);
4040
status = await commandsApi.status({
41-
clusterId: integSetup.clusterId,
41+
clusterId: integSetup.cluster.id,
4242
contextId: context.id,
4343
commandId: command.id,
4444
});
@@ -55,7 +55,7 @@ describe(__filename, function () {
5555
assert.equal(status.results.data, "juhu");
5656

5757
await executionContextApi.destroy({
58-
clusterId: integSetup.clusterId,
58+
clusterId: integSetup.cluster.id,
5959
contextId: context.id,
6060
});
6161
});

packages/databricks-sdk-js/src/apis/jobs.integ.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe(__filename, function () {
3232
tasks: [
3333
{
3434
task_key: "hello_world",
35-
existing_cluster_id: integSetup.clusterId,
35+
existing_cluster_id: integSetup.cluster.id,
3636
spark_python_task: {
3737
python_file: `dbfs:${jobPath}`,
3838
},

packages/databricks-sdk-js/src/services/Cluster.integ.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,25 @@ describe(__filename, function () {
1515
});
1616

1717
it("should create an execution context", async () => {
18-
let cluster = await Cluster.fromClusterId(
19-
integSetup.client,
20-
integSetup.clusterId
21-
);
22-
23-
await cluster.canExecute();
18+
await integSetup.cluster.canExecute();
2419

25-
let ctx = await cluster.createExecutioncontext();
26-
let command = await ctx.execute("print('hello')");
27-
let result = await command.response();
20+
let ctx = await integSetup.cluster.createExecutionContext();
21+
let {result} = await ctx.execute("print('hello')");
2822

2923
assert(result.results);
3024
assert(result.results.resultType === "text");
3125
assert.equal(result.results.data, "hello");
3226
});
3327

3428
it("should load a cluster by name", async () => {
35-
let clusterA = await Cluster.fromClusterId(
36-
integSetup.client,
37-
integSetup.clusterId
38-
);
29+
let clusterA = integSetup.cluster;
3930

4031
let clusterB = await Cluster.fromClusterName(
4132
integSetup.client,
4233
clusterA.details.cluster_name!
4334
);
4435

45-
assert(clusterA.details.cluster_id);
46-
assert.equal(clusterA.details.cluster_id, clusterB?.details.cluster_id);
36+
assert(clusterA.id);
37+
assert.equal(clusterA.id, clusterB?.id);
4738
});
4839
});

packages/databricks-sdk-js/src/services/Cluster.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,15 @@ export class Cluster {
100100
}
101101
}
102102

103-
async createExecutioncontext(): Promise<ExecutionContext> {
104-
return await ExecutionContext.create(
105-
this.client,
106-
this.clusterDetails.cluster_id!
107-
);
103+
async createExecutionContext(): Promise<ExecutionContext> {
104+
return await ExecutionContext.create(this.client, this);
108105
}
109106

110107
async canExecute(): Promise<boolean> {
111108
let context: ExecutionContext | undefined;
112109
try {
113-
context = await this.createExecutioncontext();
114-
let command = await context.execute("print('hello')");
115-
await command.response();
110+
context = await this.createExecutionContext();
111+
await context.execute("print('hello')");
116112
return true;
117113
} catch (e) {
118114
return false;

packages/databricks-sdk-js/src/services/Command.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import EventEmitter from "node:events";
22
import {CommandsService, CommandsStatusResponse} from "../apis/commands";
3-
import {Language} from "../apis/executionContext";
43
import {ExecutionContext} from "./ExecutionContext";
54

5+
export interface CommandWithResult {
6+
cmd: Command;
7+
result: CommandsStatusResponse;
8+
}
9+
10+
export type StatusUpdateListener = (result: CommandsStatusResponse) => void;
11+
612
export class Command extends EventEmitter {
713
readonly context: ExecutionContext;
814
readonly commandsApi: CommandsService;
915
id?: string;
1016

17+
private static statusUpdateEvent: string = "statusUpdate";
18+
1119
constructor(context: ExecutionContext) {
1220
super();
1321
this.context = context;
@@ -17,12 +25,12 @@ export class Command extends EventEmitter {
1725
async response(): Promise<CommandsStatusResponse> {
1826
while (true) {
1927
let result = await this.commandsApi.status({
20-
clusterId: this.context.clusterId,
28+
clusterId: this.context.cluster.id,
2129
contextId: this.context.id!,
2230
commandId: this.id!,
2331
});
2432

25-
this.emit("statusUpdate", result);
33+
this.emit(Command.statusUpdateEvent, result);
2634

2735
if (
2836
result.status === "Cancelled" ||
@@ -41,19 +49,23 @@ export class Command extends EventEmitter {
4149
static async execute(
4250
context: ExecutionContext,
4351
command: string,
44-
language: Language = "python"
45-
): Promise<Command> {
52+
onStatusUpdate: StatusUpdateListener = () => {}
53+
): Promise<CommandWithResult> {
4654
//console.log(`Executing (${language}): ${command}`);
4755
let cmd = new Command(context);
4856

57+
cmd.on(Command.statusUpdateEvent, onStatusUpdate);
58+
4959
let result = await cmd.commandsApi.execute({
50-
clusterId: cmd.context.clusterId,
60+
clusterId: cmd.context.cluster.id,
5161
contextId: cmd.context.id!,
52-
language,
62+
language: cmd.context.language,
5363
command,
5464
});
5565

5666
cmd.id = result.id;
57-
return cmd;
67+
const executionResult = await cmd.response();
68+
69+
return {cmd: cmd, result: executionResult};
5870
}
5971
}

packages/databricks-sdk-js/src/services/ExecutionContext.integ.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,20 @@ describe(__filename, function () {
1717
it("should run python with high level API", async () => {
1818
let context = await ExecutionContext.create(
1919
integSetup.client,
20-
integSetup.clusterId
20+
integSetup.cluster
2121
);
2222

23-
var command = await context.execute("print('juhu')");
24-
2523
let statusUpdateCalled = false;
26-
command.on("statusUpdate", (e) => (statusUpdateCalled = true));
27-
28-
var result = await command.response();
29-
// console.log(result);
24+
var {cmd, result} = await context.execute(
25+
"print('juhu')",
26+
(e) => (statusUpdateCalled = true)
27+
);
3028

31-
command = await context.execute("print('kinners')");
32-
result = await command.response();
33-
// console.log(result);
29+
statusUpdateCalled = false;
30+
({cmd, result} = await context.execute(
31+
"print('kinners')",
32+
(e) => (statusUpdateCalled = true)
33+
));
3434

3535
assert(statusUpdateCalled);
3636
assert(result.results);

packages/databricks-sdk-js/src/services/ExecutionContext.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
1+
import {cluster} from "..";
12
import {ApiClient} from "../api-client";
23
import {ExecutionContextService, Language} from "../apis/executionContext";
3-
import {Command} from "./Command";
4+
import {Cluster} from "./Cluster";
5+
import {Command, CommandWithResult, StatusUpdateListener} from "./Command";
46

57
export class ExecutionContext {
68
readonly executionContextApi: ExecutionContextService;
7-
readonly clusterId: string;
8-
readonly client: ApiClient;
99
id?: string;
1010

11-
constructor(client: ApiClient, clusterId: string) {
12-
this.client = client;
11+
constructor(
12+
readonly client: ApiClient,
13+
readonly cluster: Cluster,
14+
readonly language: Language
15+
) {
1316
this.executionContextApi = new ExecutionContextService(client);
14-
this.clusterId = clusterId;
1517
}
1618

1719
static async create(
1820
client: ApiClient,
19-
clusterId: string
21+
cluster: Cluster,
22+
language: Language = "python"
2023
): Promise<ExecutionContext> {
21-
let context = new ExecutionContext(client, clusterId);
24+
let context = new ExecutionContext(client, cluster, language);
2225
let response = await context.executionContextApi.create({
23-
clusterId: context.clusterId,
24-
language: "python",
26+
clusterId: context.cluster.id,
27+
language: context.language,
2528
});
2629

2730
context.id = response.id;
@@ -30,9 +33,9 @@ export class ExecutionContext {
3033

3134
async execute(
3235
command: string,
33-
language: Language = "python"
34-
): Promise<Command> {
35-
return await Command.execute(this, command, language);
36+
onStatusUpdate: StatusUpdateListener = () => {}
37+
): Promise<CommandWithResult> {
38+
return await Command.execute(this, command, onStatusUpdate);
3639
}
3740

3841
async destroy() {
@@ -41,7 +44,7 @@ export class ExecutionContext {
4144
}
4245

4346
await this.executionContextApi.destroy({
44-
clusterId: this.clusterId,
47+
clusterId: this.cluster.id,
4548
contextId: this.id,
4649
});
4750
}

packages/databricks-sdk-js/src/services/WorkflowRun.integ.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe(__filename, function () {
1515
it("should run a python job", async () => {
1616
let cluster = await Cluster.fromClusterId(
1717
integSetup.client,
18-
integSetup.clusterId
18+
integSetup.cluster.id
1919
);
2020

2121
let dbfsApi = new DbfsService(integSetup.client);
@@ -55,7 +55,7 @@ describe(__filename, function () {
5555
it("should run a notebook job", async () => {
5656
let cluster = await Cluster.fromClusterId(
5757
integSetup.client,
58-
integSetup.clusterId
58+
integSetup.cluster.id
5959
);
6060

6161
let jobPath = `/tmp/sdk-js-integ-${integSetup.testRunId}.py`;

packages/databricks-sdk-js/src/test/IntegrationTestSetup.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
import {v4 as uuidv4} from "uuid";
44
import {ApiClient} from "../api-client";
55
import {ClusterService} from "../apis/cluster";
6+
import {Cluster} from "../services/Cluster";
67

78
export class IntegrationTestSetup {
89
readonly testRunId: string;
910

10-
constructor(readonly client: ApiClient, readonly clusterId: string) {
11+
constructor(readonly client: ApiClient, readonly cluster: Cluster) {
1112
this.testRunId = uuidv4();
1213
}
1314

1415
private static _instance: IntegrationTestSetup;
1516
static async getInstance(): Promise<IntegrationTestSetup> {
1617
if (!this._instance) {
1718
let client = new ApiClient();
18-
let clustersApi = new ClusterService(client);
1919

2020
if (!process.env["TEST_DEFAULT_CLUSTER_ID"]) {
2121
throw new Error(
@@ -25,20 +25,13 @@ export class IntegrationTestSetup {
2525

2626
const clusterId =
2727
process.env["TEST_DEFAULT_CLUSTER_ID"]!.split("'").join("");
28-
clustersApi.start({cluster_id: clusterId});
2928

29+
const cluster = await Cluster.fromClusterId(client, clusterId);
30+
cluster.start();
3031
// wait for cluster to be running
31-
while (true) {
32-
let cluster = await clustersApi.get({cluster_id: clusterId});
33-
if (cluster.state === "RUNNING") {
34-
break;
35-
}
36-
37-
await new Promise((resolve) => {
38-
setTimeout(resolve, 1000);
39-
});
40-
}
41-
this._instance = new IntegrationTestSetup(client, clusterId);
32+
await cluster.waitForState("RUNNING");
33+
34+
this._instance = new IntegrationTestSetup(client, cluster);
4235
}
4336
return this._instance;
4437
}

0 commit comments

Comments
 (0)