Skip to content

Commit

Permalink
Merge of #6281
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Apr 30, 2024
2 parents bb52687 + b37c17b commit f18a82e
Show file tree
Hide file tree
Showing 17 changed files with 435 additions and 49 deletions.
15 changes: 9 additions & 6 deletions docs/docs/04-standard-library/cloud/topic.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,18 @@ topic.subscribeQueue(queue);

### Publishing to a topic

The inflight method `publish` sends a message to all of the topic's subscribers.
The inflight method `publish` sends messages to all of the topic's subscribers.

```js
bring cloud;

let topic = new cloud.Topic();

inflight () => {
topic.publish("Hello World!");
topic.publish(
"Topics can now publish",
"multiple messages at once"
);
};
```

Expand Down Expand Up @@ -155,7 +158,7 @@ new cloud.Topic(props?: TopicProps);

| **Name** | **Description** |
| --- | --- |
| <code><a href="#@winglang/sdk.cloud.ITopicClient.publish">publish</a></code> | Publish message to topic. |
| <code><a href="#@winglang/sdk.cloud.ITopicClient.publish">publish</a></code> | Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform. |

---

Expand Down Expand Up @@ -202,12 +205,12 @@ Subscribing queue to the topic.
##### `publish` <a name="publish" id="@winglang/sdk.cloud.ITopicClient.publish"></a>

```wing
inflight publish(message: str): void
inflight publish(...messages: Array<str>): void
```

Publish message to topic.
Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.

###### `message`<sup>Required</sup> <a name="message" id="@winglang/sdk.cloud.ITopicClient.publish.parameter.message"></a>
###### `messages`<sup>Required</sup> <a name="messages" id="@winglang/sdk.cloud.ITopicClient.publish.parameter.messages"></a>

- *Type:* str

Expand Down
17 changes: 17 additions & 0 deletions examples/tests/sdk_tests/topic/variadic-parameter.test.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bring cloud;
bring util;

let c = new cloud.Counter();
let t = new cloud.Topic();
t.onMessage(inflight (msg: str) => {
c.inc();
});

test "publish message array to topic" {
t.publish("msg1", "msg2", "msg3",
"msg4", "msg5", "msg6", "msg7",
"msg8", "msg9", "msg10", "msg11",
"msg12", "msg13", "msg14", "msg15");

assert(util.waitUntil(inflight () => { return c.peek() == 15; }));
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 7
documentation:
kind: markdown
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
sortText: gg|Topic
- label: Website
kind: 7
Expand Down Expand Up @@ -515,7 +515,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 8
documentation:
kind: markdown
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (message: str): void` — Publish message to topic."
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform."
sortText: ii|ITopicClient
- label: ITopicOnMessageHandler
kind: 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 7
documentation:
kind: markdown
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
sortText: gg|Topic
- label: Website
kind: 7
Expand Down Expand Up @@ -515,7 +515,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 8
documentation:
kind: markdown
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (message: str): void` — Publish message to topic."
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform."
sortText: ii|ITopicClient
- label: ITopicOnMessageHandler
kind: 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 7
documentation:
kind: markdown
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
sortText: gg|Topic
insertText: Topic($1)
insertTextFormat: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 7
documentation:
kind: markdown
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
sortText: gg|Topic
- label: Website
kind: 7
Expand Down Expand Up @@ -515,7 +515,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 8
documentation:
kind: markdown
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (message: str): void` — Publish message to topic."
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform."
sortText: ii|ITopicClient
- label: ITopicOnMessageHandler
kind: 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 7
documentation:
kind: markdown
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array<str>): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct."
sortText: gg|Topic
- label: Website
kind: 7
Expand Down Expand Up @@ -515,7 +515,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 8
documentation:
kind: markdown
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (message: str): void` — Publish message to topic."
value: "```wing\ninterface ITopicClient\n```\n---\nInflight interface for `Topic`.\n### Methods\n- `publish` — `inflight (...messages: Array<str>?): void` — Publish messages to topic, if multiple messages are passed then they will be published as a batch if supported by the target platform."
sortText: ii|ITopicClient
- label: ITopicOnMessageHandler
kind: 8
Expand Down
7 changes: 5 additions & 2 deletions libs/wingsdk/src/cloud/topic.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,18 @@ topic.subscribeQueue(queue);

### Publishing to a topic

The inflight method `publish` sends a message to all of the topic's subscribers.
The inflight method `publish` sends messages to all of the topic's subscribers.

```js
bring cloud;

let topic = new cloud.Topic();

inflight () => {
topic.publish("Hello World!");
topic.publish(
"Topics can now publish",
"multiple messages at once"
);
};
```

Expand Down
7 changes: 4 additions & 3 deletions libs/wingsdk/src/cloud/topic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ export interface TopicSubscribeQueueOptions extends QueueProps {}
*/
export interface ITopicClient {
/**
* Publish message to topic
* @param message Payload to publish to Topic
* Publish messages to topic, if multiple messages are passed then they
* will be published as a batch if supported by the target platform
* @param messages Payload to publish to Topic
* @inflight
*/
publish(message: string): Promise<void>;
publish(...messages: string[]): void;
}

/**
Expand Down
65 changes: 58 additions & 7 deletions libs/wingsdk/src/shared-aws/topic.inflight.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,68 @@
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
import {
SNSClient,
PublishBatchCommand,
PublishBatchRequestEntry,
InvalidBatchEntryIdException,
} from "@aws-sdk/client-sns";
import { ITopicClient } from "../cloud";
import { Util } from "../util/util";

/**
* Topics in AWS can receive up to 10 messages at a time
* using the PublishBatchCommand, this constant is used
* to generate batches respecting the limits.
*/
const CHUNK_SIZE = 10;

export class TopicClient implements ITopicClient {
constructor(
private readonly topicArn: string,
private readonly client: SNSClient = new SNSClient({})
) {}

public async publish(message: string): Promise<void> {
const command = new PublishCommand({
Message: message,
TopicArn: this.topicArn,
});
await this.client.send(command);
public async publish(...messages: string[]): Promise<void> {
if (messages.includes("")) {
throw new Error("Empty messages are not allowed");
}

let batchMessages: Array<PublishBatchRequestEntry[]> = [];
for (let i = 0; i < messages.length; i += CHUNK_SIZE) {
const chunk = messages.slice(i, i + CHUNK_SIZE);
batchMessages.push(this.processBatchMessages(chunk, i));
}

for (const batch of batchMessages) {
try {
const command = new PublishBatchCommand({
TopicArn: this.topicArn,
PublishBatchRequestEntries: batch,
});
await this.client.send(command);
} catch (e) {
if (e instanceof InvalidBatchEntryIdException) {
throw new Error(
`The Id of a batch entry in a batch request doesn't abide by the specification. (message=${messages}): ${
(e as Error).stack
})}`
);
}
throw new Error((e as Error).stack);
}
}
}

private processBatchMessages(
messages: string[],
idx: number
): PublishBatchRequestEntry[] {
let batchMessages: Array<PublishBatchRequestEntry> = [];
let index = idx;
for (const message of messages) {
batchMessages.push({
Id: Util.sha256(`${message}-${++index}`),
Message: message,
});
}
return batchMessages;
}
}
Loading

0 comments on commit f18a82e

Please sign in to comment.