Skip to content

Commit

Permalink
connect: use the public /v1/tasks/{id} endpoint
Browse files Browse the repository at this point in the history
* deployApp() continues to return a v0 task
* getTask() accepts first and wait arguments and returns a v1 task
* ClientTaskPoller uses long-polling rather than sleeping; returns a result with "output" rather than "status"

fixes #38
  • Loading branch information
aronatkins committed Jun 28, 2024
1 parent f272cff commit 783a4a8
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 40 deletions.
10 changes: 6 additions & 4 deletions __tests__/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ describe('rsconnect', () => {
.then(async (poller: rsconnect.ClientTaskPoller) => {
for await (const result of poller.poll()) {
expect(result).not.toBeNull()
expect(result.status).not.toBeNull()
expect(result.status.length).toBeGreaterThan(-1)
expect(result.output).not.toBeNull()
expect(result.output.length).toBeGreaterThan(-1)
// console.log(result.output)
}
})
.catch((err: any) => {
Expand All @@ -97,8 +98,9 @@ describe('rsconnect', () => {
.then(async (poller: rsconnect.ClientTaskPoller) => {
for await (const result of poller.poll()) {
expect(result).not.toBeNull()
expect(result.status).not.toBeNull()
expect(result.status.length).toBeGreaterThan(-1)
expect(result.output).not.toBeNull()
expect(result.output.length).toBeGreaterThan(-1)
// console.log(result.output)
}
})
.catch((err: any) => {
Expand Down
20 changes: 11 additions & 9 deletions src/APIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { debugLog, debugEnabled } from './debugLog'
import {
Application,
AppEnvironmentResponse,
ClientTaskResponse,
ClientTaskV0Response,
ClientTaskV1Params,
ClientTaskV1Response,
ExtendedBundleResponse,
ListApplicationsParams,
ListApplicationsResponse,
Expand Down Expand Up @@ -118,7 +120,7 @@ export class APIClient {
).then((resp: AxiosResponse) => keysToCamel(resp.data))
}

public async deployApp (appID: number, bundleID: number): Promise<ClientTaskResponse> {
public async deployApp (appID: number, bundleID: number): Promise<ClientTaskV0Response> {
return await this.client.post(
`applications/${appID}/deploy`,
{ bundle: bundleID }
Expand Down Expand Up @@ -155,13 +157,13 @@ export class APIClient {
)
}

public async getTask (taskId: string, status?: number): Promise<ClientTaskResponse> {
return await this.client.get(
`tasks/${taskId}`,
status !== null && status !== undefined
? { params: { first_status: status } }
: undefined
).then((resp: AxiosResponse) => keysToCamel(resp.data))
public async getTask (taskId: string, first?: number, wait?: number): Promise<ClientTaskV1Response> {
const params: ClientTaskV1Params = {
first: (first !== null && first !== undefined) ? first : undefined,
wait: (wait !== null && wait !== undefined) ? wait : undefined
}
return await this.client.get(`v1/tasks/${taskId}`, { params })
.then((resp: AxiosResponse) => keysToCamel(resp.data))
}

public async getBundle (bundleId: number): Promise<ExtendedBundleResponse> {
Expand Down
36 changes: 12 additions & 24 deletions src/ClientTaskPoller.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { debugLog } from './debugLog'
import { APIClient } from './APIClient'
import { ClientTaskResponse } from './api-types'
import { ClientTaskV1Response } from './api-types'

export class ClientTaskPoller {
private readonly client: APIClient
private readonly taskId: string
private readonly sleepInterval: number
private readonly wait: number

constructor (client: APIClient, taskId: string, sleepInterval?: number) {
constructor (client: APIClient, taskId: string, wait?: number) {
this.client = client
this.taskId = taskId
this.sleepInterval = (
sleepInterval !== null && sleepInterval !== undefined
? sleepInterval
: 500
)
this.wait = (wait !== null && wait !== undefined) ? wait : 1
}

public async * poll (timeout?: number): AsyncGenerator<ClientTaskPollResult> {
Expand All @@ -23,28 +19,26 @@ export class ClientTaskPoller {
? ((Date.now() / 1000 | 0) + timeout)
: Infinity
)
let lastStatus: number | undefined
let first: number | undefined
while ((Date.now() / 1000 | 0) < pollTimeout) {
if (this.taskId === '') {
debugLog(() => 'ClientTaskPollResult: returning due to empty task id')
return
}

debugLog(() => `ClientTaskPollResult: sleeping ${JSON.stringify(this.sleepInterval)}`)
await this.sleepTick()

debugLog(() => [
'ClientTaskPollResult: getting',
`task=${JSON.stringify(this.taskId)}`,
`lastStatus=${JSON.stringify(lastStatus)}`
`first=${JSON.stringify(first)}`,
`wait=${JSON.stringify(this.wait)}`
].join(' '))

const curTask: ClientTaskResponse = await this.client.getTask(
this.taskId, lastStatus
const curTask: ClientTaskV1Response = await this.client.getTask(
this.taskId, first, this.wait
)

const res = {
status: curTask.status,
output: curTask.output,
type: curTask.result?.type,
data: curTask.result?.data
}
Expand All @@ -56,23 +50,17 @@ export class ClientTaskPoller {

yield res

lastStatus = curTask.lastStatus
first = curTask.last
if (curTask.finished) {
debugLog(() => 'ClientTaskPollResult: returning due to finished')
return
}
}
}

private async sleepTick (): Promise<void> {
return await new Promise((resolve: any) => {
setTimeout(() => resolve(), this.sleepInterval)
})
}
}

export interface ClientTaskPollResult {
status: string[]
output: string[]
type?: string
data?: any
}
4 changes: 2 additions & 2 deletions src/Deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { debugLog } from './debugLog'
import { APIClient } from './APIClient'
import { Bundle } from './Bundle'
import { Bundler } from './Bundler'
import { Application, ClientTaskResponse, ListApplicationsResponse } from './api-types'
import { Application, ClientTaskV0Response, ListApplicationsResponse } from './api-types'
import { ApplicationPather } from './ApplicationPather'

export interface DeployManifestParams {
Expand Down Expand Up @@ -208,7 +208,7 @@ export class Deployer {
].join(' '))

return await this.client.deployApp(app.id, uploadedBundle.id)
.then((ct: ClientTaskResponse) => {
.then((ct: ClientTaskV0Response) => {
return {
appGuid: app.guid,
appId: app.id,
Expand Down
17 changes: 16 additions & 1 deletion src/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface Application {
git?: AppGitRecord
}

export interface ClientTaskResponse {
export interface ClientTaskV0Response {
id: string
userId: number
status: string[]
Expand All @@ -65,6 +65,21 @@ export interface ClientTaskResponse {
lastStatus: number
}

export interface ClientTaskV1Params {
first?: number
wait?: number
}

export interface ClientTaskV1Response {
id: string
output: string[]
result?: ClientTaskResult
finished: boolean
code: number
error: string
last: number
}

export interface ClientTaskResult {
type: string
data: any
Expand Down

0 comments on commit 783a4a8

Please sign in to comment.