-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
448 additions
and
14 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
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,17 @@ | ||
import { strict as assert } from 'assert'; | ||
import { Client } from 'layotto'; | ||
|
||
const client = new Client(); | ||
assert(client); | ||
|
||
async function main() { | ||
const pubsubName = 'redis'; | ||
const topic = 'topic1'; | ||
const value = `bar, from js-sdk, ${Date()}`; | ||
|
||
await client.pubsub.publish({ | ||
pubsubName, topic, data: { value }, | ||
}); | ||
} | ||
|
||
main(); |
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,31 @@ | ||
/* | ||
* Copyright 2021 Layotto Authors | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { strict as assert } from 'assert' | ||
import { Client } from 'layotto'; | ||
|
||
const client = new Client(); | ||
assert(client); | ||
|
||
async function main() { | ||
const pubsubName = 'redis'; | ||
const topic = 'topic1'; | ||
const value = `bar, from js-sdk, ${Date()}`; | ||
|
||
await client.pubsub.publish({ | ||
pubsubName, topic, data: { value }, | ||
}); | ||
} | ||
|
||
main(); |
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,12 @@ | ||
import { Server } from 'layotto'; | ||
|
||
async function main() { | ||
const server = new Server(); | ||
server.pubsub.subscribe('redis', 'topic1', async (data) => { | ||
console.log('topic1 event data: %j', data); | ||
}); | ||
|
||
await server.start(); | ||
} | ||
|
||
main(); |
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
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
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
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
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
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,39 @@ | ||
/* | ||
* Copyright 2021 Layotto Authors | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { | ||
PublishEventRequest as PublishEventRequestPB, | ||
} from '../../proto/runtime_pb'; | ||
import { API } from './API'; | ||
import { PublishEventRequest } from '../types/PubSub'; | ||
|
||
export default class PubSub extends API { | ||
async publish(request: PublishEventRequest): Promise<void> { | ||
const req = new PublishEventRequestPB(); | ||
req.setPubsubName(request.pubsubName); | ||
req.setTopic(request.topic); | ||
// https://mosn.io/layotto/#/zh/design/pubsub/pubsub-api-and-compability-with-dapr-component | ||
// PublishRequest.Data 和 NewMessage.Data 里面放符合 CloudEvent 1.0 规范的 json 数据(能反序列化放进 map[string]interface{}) | ||
req.setData(Buffer.from(JSON.stringify(request.data))); | ||
req.setDataContentType('application/json'); | ||
// FIXME: metadata | ||
|
||
return new Promise((resolve, reject) => { | ||
this.runtime.publishEvent(req, this.createMetadata(request), (err) => { | ||
if (err) return reject(err); | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
} |
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
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,86 @@ | ||
import { debuglog } from 'node:util'; | ||
import * as grpc from '@grpc/grpc-js'; | ||
import { Empty } from 'google-protobuf/google/protobuf/empty_pb'; | ||
import { IAppCallbackServer } from '../../proto/appcallback_grpc_pb'; | ||
import { | ||
ListTopicSubscriptionsResponse, | ||
TopicSubscription, | ||
TopicEventRequest, | ||
TopicEventResponse, | ||
} from '../../proto/appcallback_pb'; | ||
import { PubSubCallback } from '../types/PubSub'; | ||
|
||
const debug = debuglog('layotto:server:grpc'); | ||
|
||
// @ts-ignore | ||
export default class GRPCServerImpl implements IAppCallbackServer { | ||
private readonly _handlersTopics: { [key: string]: PubSubCallback }; | ||
constructor() { | ||
this._handlersTopics = {}; | ||
} | ||
|
||
private createPubSubHandlerKey(pubsubName: string, topic: string): string { | ||
return `${pubsubName}|${topic}`.toLowerCase(); | ||
} | ||
|
||
registerPubSubSubscriptionHandler(pubsubName: string, topic: string, callback: PubSubCallback): void { | ||
const handlerKey = this.createPubSubHandlerKey(pubsubName, topic); | ||
if (this._handlersTopics[handlerKey]) { | ||
throw new Error(`Topic: "${handlerKey}" handler was exists`); | ||
} | ||
this._handlersTopics[handlerKey] = callback; | ||
debug('PubSub Event from topic: "%s" is registered', handlerKey); | ||
} | ||
|
||
async onTopicEvent(call: grpc.ServerUnaryCall<TopicEventRequest, TopicEventResponse>, | ||
callback: grpc.sendUnaryData<TopicEventResponse>): Promise<void> { | ||
const req = call.request; | ||
const res = new TopicEventResponse(); | ||
const handlerKey = this.createPubSubHandlerKey(req.getPubsubName(), req.getTopic()); | ||
|
||
const handler = this._handlersTopics[handlerKey]; | ||
if (!handler) { | ||
debug('PubSub Event from topic: "%s" was not handled, drop now', handlerKey); | ||
// FIXME: should retry? | ||
res.setStatus(TopicEventResponse.TopicEventResponseStatus.DROP); | ||
return callback(null, res); | ||
} | ||
|
||
// https://mosn.io/layotto/#/zh/design/pubsub/pubsub-api-and-compability-with-dapr-component | ||
// PublishRequest.Data 和 NewMessage.Data 里面放符合 CloudEvent 1.0 规范的 json 数据(能反序列化放进 map[string]interface{}) | ||
const rawData = Buffer.from(req.getData_asU8()).toString(); | ||
debug('PubSub Event from topic: "%s" raw data: %j, typeof %s', handlerKey, rawData, typeof rawData); | ||
let data; | ||
try { | ||
data = JSON.parse(rawData); | ||
} catch { | ||
data = rawData; | ||
} | ||
|
||
try { | ||
await handler(data); | ||
res.setStatus(TopicEventResponse.TopicEventResponseStatus.SUCCESS); | ||
} catch (e) { | ||
// FIXME: should retry? | ||
debug('PubSub Event from topic: "%s" handler throw error: %s, drop now', handlerKey, e); | ||
res.setStatus(TopicEventResponse.TopicEventResponseStatus.DROP); | ||
} | ||
|
||
callback(null, res); | ||
} | ||
|
||
async listTopicSubscriptions(_call: grpc.ServerUnaryCall<Empty, ListTopicSubscriptionsResponse>, | ||
callback: grpc.sendUnaryData<ListTopicSubscriptionsResponse>): Promise<void> { | ||
const res = new ListTopicSubscriptionsResponse(); | ||
const subscriptionsList = Object.keys(this._handlersTopics).map(key => { | ||
const splits = key.split('|'); | ||
const sub = new TopicSubscription(); | ||
sub.setPubsubName(splits[0]); | ||
sub.setTopic(splits[1]); | ||
return sub; | ||
}); | ||
debug('listTopicSubscriptions call: %j', subscriptionsList); | ||
res.setSubscriptionsList(subscriptionsList); | ||
callback(null, res); | ||
} | ||
} |
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,18 @@ | ||
import { debuglog } from 'node:util'; | ||
import { PubSubCallback } from '../types/PubSub'; | ||
import GRPCServerImpl from './GRPCServerImpl'; | ||
|
||
const debug = debuglog('layotto:server:pubsub'); | ||
|
||
export default class PubSub { | ||
readonly server: GRPCServerImpl; | ||
|
||
constructor(server: GRPCServerImpl) { | ||
this.server = server; | ||
} | ||
|
||
async subscribe(pubsubName: string, topic: string, cb: PubSubCallback): Promise<void> { | ||
debug('Registering onTopicEvent Handler: PubSub = %s, Topic = %s', pubsubName, topic); | ||
this.server.registerPubSubSubscriptionHandler(pubsubName, topic, cb); | ||
} | ||
} |
Oops, something went wrong.