Skip to content

Commit 5b325d4

Browse files
author
Alexey Temnikov
committed
Added ability to poll the changes
1 parent 7d73e91 commit 5b325d4

File tree

16 files changed

+203
-9
lines changed

16 files changed

+203
-9
lines changed

packages/core/src/docdb/commands/startCluster.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ export function startCluster(node?: DBClusterNode): Promise<void> {
1717
void vscode.window.showInformationMessage(
1818
localize('AWS.docdb.startCluster.success', 'Starting cluster: {0}', node.name)
1919
)
20-
await node.waitUntilStatusChanged()
21-
node?.parent.refresh()
2220
}
2321
})
2422
}

packages/core/src/docdb/commands/stopCluster.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ export function stopCluster(node?: DBClusterNode): Promise<void> {
3434
void vscode.window.showInformationMessage(
3535
localize('AWS.docdb.stopCluster.success', 'Stopping cluster: {0}', node.name)
3636
)
37-
await node.waitUntilStatusChanged()
38-
node?.parent.refresh()
3937
}
4038
})
4139
}

packages/core/src/docdb/explorer/dbClusterNode.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { DBInstance, DocumentDBClient } from '../../shared/clients/docdbClient'
1919
import { DocDBContext } from './docdbContext'
2020
import { toTitleCase } from '../../shared'
2121
import { getAwsConsoleUrl } from '../../shared/awsConsole'
22+
import { getLogger } from '../../shared/logger'
2223

2324
export type DBClusterRole = 'global' | 'regional' | 'primary' | 'secondary'
2425

@@ -31,6 +32,7 @@ export class DBClusterNode extends DBResourceNode {
3132
override name = this.cluster.DBClusterIdentifier!
3233
override arn = this.cluster.DBClusterArn!
3334
public instances: DBInstance[] = []
35+
private childNodes: DBInstanceNode[] = []
3436

3537
constructor(
3638
public readonly parent: AWSTreeNodeBase,
@@ -39,6 +41,7 @@ export class DBClusterNode extends DBResourceNode {
3941
readonly clusterRole: DBClusterRole = 'regional'
4042
) {
4143
super(client, cluster.DBClusterIdentifier ?? '[Cluster]', vscode.TreeItemCollapsibleState.Collapsed)
44+
getLogger().info(`NEW DBClusterNode: ${cluster.DBClusterArn}`)
4245
this.arn = cluster.DBClusterArn ?? ''
4346
this.name = cluster.DBClusterIdentifier ?? ''
4447
this.contextValue = this.getContext()
@@ -47,10 +50,16 @@ export class DBClusterNode extends DBResourceNode {
4750
)
4851
this.description = this.getDescription()
4952
this.tooltip = `${this.name}${os.EOL}Engine: ${this.cluster.EngineVersion}${os.EOL}Status: ${this.cluster.Status}`
53+
this.trackChanges()
5054
}
5155

5256
public override async getChildren(): Promise<AWSTreeNodeBase[]> {
5357
return telemetry.docdb_listInstances.run(async () => {
58+
this.childNodes.forEach((node) => {
59+
getLogger().info(`(getChildren) Removing Polling from node: ${node.arn}`)
60+
node.pollingSet.delete(node.arn)
61+
node.pollingSet.clearTimer()
62+
})
5463
return await makeChildrenNodes({
5564
getChildNodes: async () => {
5665
this.instances = (await this.client.listInstances([this.arn])).map((i) => {
@@ -60,6 +69,7 @@ export class DBClusterNode extends DBResourceNode {
6069
return { ...i, ...member }
6170
})
6271
const nodes = this.instances.map((instance) => new DBInstanceNode(this, instance))
72+
this.childNodes = nodes
6373
return nodes
6474
},
6575
getNoChildrenPlaceholderNode: async () => {
@@ -132,7 +142,9 @@ export class DBClusterNode extends DBResourceNode {
132142
}
133143

134144
override async getStatus() {
135-
const [cluster] = await this.client.listClusters(this.id)
145+
const [cluster] = await this.client.listClusters(this.arn)
146+
getLogger().info(`Updating Status: new status ${cluster?.Status} for cluster ${this.arn}`)
147+
this.cluster.Status = cluster?.Status
136148
return cluster.Status
137149
}
138150

@@ -149,6 +161,22 @@ export class DBClusterNode extends DBResourceNode {
149161
return Promise.reject()
150162
}
151163

164+
override refreshTree(): void {
165+
this.clearTimer()
166+
this.refresh()
167+
this.parent.refresh()
168+
}
169+
170+
override clearTimer(): void {
171+
this.pollingSet.delete(this.arn)
172+
this.pollingSet.clearTimer()
173+
this.childNodes.forEach((node) => {
174+
getLogger().info(`(clearTimer) Removing Polling from node: ${node.arn}`)
175+
node.pollingSet.delete(node.arn)
176+
node.pollingSet.clearTimer()
177+
})
178+
}
179+
152180
public [inspect.custom](): string {
153181
return 'DBClusterNode'
154182
}

packages/core/src/docdb/explorer/dbElasticClusterNode.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ export class DBElasticClusterNode extends DBResourceNode {
9191
await copyToClipboard(this.cluster.clusterEndpoint!, this.name)
9292
}
9393

94+
override refreshTree(): void {
95+
this.refresh()
96+
this.parent.refresh()
97+
}
98+
99+
override clearTimer(): void {
100+
this.pollingSet.delete(this.arn)
101+
this.pollingSet.clearTimer()
102+
}
103+
94104
public [inspect.custom](): string {
95105
return 'DBElasticClusterNode'
96106
}

packages/core/src/docdb/explorer/dbGlobalClusterNode.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export class DBGlobalClusterNode extends DBResourceNode {
5858
const nodes = members.map((member) => {
5959
const memberRole: DBClusterRole = member.IsWriter ? 'primary' : 'secondary'
6060
const [cluster, client] = this.clusterMap.get(member.DBClusterArn!) ?? []
61+
6162
return new DBClusterNode(this, cluster!, client!, memberRole)
6263
})
6364

@@ -133,6 +134,16 @@ export class DBGlobalClusterNode extends DBResourceNode {
133134
})
134135
}
135136

137+
override refreshTree(): void {
138+
this.refresh()
139+
this.parent.refresh()
140+
}
141+
142+
override clearTimer(): void {
143+
this.pollingSet.delete(this.arn)
144+
this.pollingSet.clearTimer()
145+
}
146+
136147
public [inspect.custom](): string {
137148
return 'DBGlobalClusterNode'
138149
}

packages/core/src/docdb/explorer/dbInstanceNode.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ModifyDBInstanceMessage } from '@aws-sdk/client-docdb'
1313
import { copyToClipboard } from '../../shared/utilities/messages'
1414
import { toTitleCase } from '../../shared'
1515
import { getAwsConsoleUrl } from '../../shared/awsConsole'
16+
import { getLogger } from '../../shared/logger'
1617

1718
/**
1819
* An AWS Explorer node representing a DocumentDB instance.
@@ -26,10 +27,12 @@ export class DBInstanceNode extends DBResourceNode {
2627
readonly instance: DBInstance
2728
) {
2829
super(parent.client, instance.DBInstanceIdentifier ?? '[Instance]', vscode.TreeItemCollapsibleState.None)
30+
getLogger().info(`NEW DBInstanceNode: ${instance.DBInstanceArn}`)
2931
this.description = this.makeDescription()
3032
this.contextValue = this.getContext()
3133
this.iconPath = this.isAvailable || this.isStopped ? undefined : new vscode.ThemeIcon('loading~spin')
3234
this.tooltip = `${this.name}\nClass: ${this.instance.DBInstanceClass}\nStatus: ${this.status}`
35+
this.trackChanges()
3336
}
3437

3538
private makeDescription(): string {
@@ -67,6 +70,7 @@ export class DBInstanceNode extends DBResourceNode {
6770

6871
override async getStatus() {
6972
const instance = await this.parent.client.getInstance(this.instance.DBInstanceIdentifier!)
73+
this.instance.DBInstanceStatus = instance?.DBInstanceStatus
7074
return instance?.DBInstanceStatus
7175
}
7276

@@ -80,6 +84,17 @@ export class DBInstanceNode extends DBResourceNode {
8084
return copyToClipboard(this.instance.Endpoint?.Address ?? '', this.name)
8185
}
8286

87+
override refreshTree(): void {
88+
this.clearTimer()
89+
this.refresh()
90+
this.parent.refresh()
91+
}
92+
93+
override clearTimer(): void {
94+
this.pollingSet.delete(this.arn)
95+
this.pollingSet.clearTimer()
96+
}
97+
8398
public [inspect.custom](): string {
8499
return 'DBInstanceNode'
85100
}

packages/core/src/docdb/explorer/dbResourceNode.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import { AWSResourceNode } from '../../shared/treeview/nodes/awsResourceNode'
99
import { AWSTreeNodeBase } from '../../shared/treeview/nodes/awsTreeNodeBase'
1010
import { DocumentDBClient } from '../../shared/clients/docdbClient'
1111
import { waitUntil } from '../../shared'
12+
import { getLogger } from '../../shared/logger'
13+
import { PollingSet } from '../../shared/utilities/pollingSet'
1214

1315
/** An AWS Explorer node representing a DocumentDB resource. */
1416
export abstract class DBResourceNode extends AWSTreeNodeBase implements AWSResourceNode {
1517
public override readonly regionCode: string
1618
public abstract readonly arn: string
1719
public abstract readonly name: string
20+
public readonly pollingSet: PollingSet<string> = new PollingSet(10000, this.updateNodeStatus.bind(this))
1821

1922
protected constructor(
2023
public readonly client: DocumentDBClient,
@@ -23,6 +26,7 @@ export abstract class DBResourceNode extends AWSTreeNodeBase implements AWSResou
2326
) {
2427
super(label, collapsibleState)
2528
this.regionCode = client.regionCode
29+
getLogger().info(`NEW DBResourceNode`)
2630
}
2731

2832
public [inspect.custom](): string {
@@ -33,6 +37,10 @@ export abstract class DBResourceNode extends AWSTreeNodeBase implements AWSResou
3337

3438
public abstract getStatus(): Promise<string | undefined>
3539

40+
public abstract refreshTree(): void
41+
42+
public abstract clearTimer(): void
43+
3644
public get isAvailable(): boolean {
3745
return this.status === 'available'
3846
}
@@ -47,14 +55,29 @@ export abstract class DBResourceNode extends AWSTreeNodeBase implements AWSResou
4755
await waitUntil(
4856
async () => {
4957
const status = await this.getStatus()
58+
getLogger().info('docdb: waitUntilStatusChanged (status): %O', status)
5059
return status !== currentStatus
5160
},
52-
{ timeout: 30000, interval: 500, truthy: true }
61+
{ timeout: 1200000, interval: 5000, truthy: true }
5362
)
5463

5564
return false
5665
}
5766

67+
public trackChanges() {
68+
getLogger().info(
69+
`Preparing to track changes for ARN: ${this.arn}; pollingSet: ${this.pollingSet.has(this.arn)}; condition: ${this.pollingSet.has(this.arn) === false}`
70+
)
71+
if (this.pollingSet.has(this.arn) === false) {
72+
this.pollingSet.start(this.arn)
73+
getLogger().info(
74+
`Tracking changes for ARN: ${this.arn}; pollingSet: ${this.pollingSet.has(this.arn)}; condition: ${this.pollingSet.has(this.arn) === false}`
75+
)
76+
} else {
77+
getLogger().info(`ARN: ${this.arn} already being tracked`)
78+
}
79+
}
80+
5881
public async listTags() {
5982
return await this.client.listResourceTags(this.arn)
6083
}
@@ -66,4 +89,18 @@ export abstract class DBResourceNode extends AWSTreeNodeBase implements AWSResou
6689
public openInBrowser() {
6790
return vscode.env.openExternal(this.getConsoleUrl())
6891
}
92+
93+
private async updateNodeStatus() {
94+
const currentStatus = this.status
95+
const newStatus = await this.getStatus()
96+
getLogger().info(
97+
`docdb: ${this.arn} updateNodeStatus (new status): ${newStatus} (old status): ${currentStatus}`
98+
)
99+
if (currentStatus !== newStatus) {
100+
getLogger().info(`docdb: ${this.arn} updateNodeStatus - refreshing UI`)
101+
this.pollingSet.delete(this.arn)
102+
this.pollingSet.clearTimer()
103+
this.refreshTree()
104+
}
105+
}
69106
}

packages/core/src/docdb/explorer/docdbNode.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { DBElasticClusterNode } from './dbElasticClusterNode'
1515
import { telemetry } from '../../shared/telemetry'
1616
import { DBGlobalClusterNode } from './dbGlobalClusterNode'
1717
import { DBCluster } from '@aws-sdk/client-docdb'
18+
import { getLogger } from '../../shared/logger'
19+
import { DBResourceNode } from './dbResourceNode'
1820

1921
/**
2022
* An AWS Explorer node representing DocumentDB.
@@ -23,6 +25,7 @@ import { DBCluster } from '@aws-sdk/client-docdb'
2325
*/
2426
export class DocumentDBNode extends AWSTreeNodeBase {
2527
public override readonly regionCode: string
28+
private allNodes: DBResourceNode[] = []
2629

2730
public constructor(public readonly client: DocumentDBClient) {
2831
super('DocumentDB', vscode.TreeItemCollapsibleState.Collapsed)
@@ -33,7 +36,9 @@ export class DocumentDBNode extends AWSTreeNodeBase {
3336
public override async getChildren(): Promise<AWSTreeNodeBase[]> {
3437
return telemetry.docdb_listClusters.run(async () => {
3538
return await makeChildrenNodes({
36-
getChildNodes: () => this.getClusterNodes(),
39+
getChildNodes: () => {
40+
return this.getClusterNodes()
41+
},
3742
getNoChildrenPlaceholderNode: async () =>
3843
new PlaceholderNode(this, localize('AWS.explorerNode.docdb.noClusters', '[No Clusters found]')),
3944
sort: (item1, item2) => item1.name.localeCompare(item2.name),
@@ -62,18 +67,22 @@ export class DocumentDBNode extends AWSTreeNodeBase {
6267

6368
// contains clusters that are not part of a global cluster
6469
const regionalClusters = clusters.filter((c) => !globalClusterMap.has(c.DBClusterArn!))
70+
this.allNodes.forEach((node) => {
71+
node.clearTimer()
72+
})
6573

66-
const nodes = []
74+
const nodes: DBResourceNode[] = []
6775
nodes.push(
6876
...globalClusters.map((cluster) => new DBGlobalClusterNode(this, cluster, globalClusterMap, this.client))
6977
)
78+
getLogger().info(`Repopulating child regional clusters...`)
7079
nodes.push(...regionalClusters.map((cluster) => new DBClusterNode(this, cluster, this.client)))
7180
nodes.push(
7281
...elasticClusters.map(
7382
(cluster) => new DBElasticClusterNode(this, cluster as DBElasticCluster, this.client)
7483
)
7584
)
76-
85+
this.allNodes = nodes
7786
return nodes
7887
}
7988

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
7+
</content>
8+
<orderEntry type="inheritedJdk" />
9+
<orderEntry type="sourceFolder" forTests="false" />
10+
</component>
11+
</module>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="true" />
7+
</content>
8+
<orderEntry type="inheritedJdk" />
9+
<orderEntry type="sourceFolder" forTests="false" />
10+
</component>
11+
</module>

0 commit comments

Comments
 (0)