Skip to content

Commit f223dd8

Browse files
committed
master merge to typescript
2 parents 5958506 + fd9675b commit f223dd8

23 files changed

+1649
-1193
lines changed

.eslintrc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ module.exports = {
8181
],
8282
rules: {
8383
"arrow-body-style": 0,
84+
camelcase: 0,
8485
"class-methods-use-this": 0,
86+
"consistent-return": 0,
8587
"comma-dangle": 0,
8688
"dot-notation": 0,
8789
"func-names": 0,
90+
"guard-for-in": 0,
8891
"import/extensions": 0,
8992
"import/no-extraneous-dependencies": 0,
9093
"import/no-unresolved": 0,
@@ -106,7 +109,7 @@ module.exports = {
106109
quotes: 0,
107110
"prefer-const": 1,
108111
"prefer-destructuring": 0,
109-
"prefer-template": 1,
112+
"prefer-template": 0,
110113
"react/button-has-type": 0,
111114
"react/destructuring-assignment": 0,
112115
"react/forbid-prop-types": 0,

SSEController.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ SSEController.createStream = (reqResObj, options, event) => {
1313
// because EventSource cannot access headers, we are making a regular get request to SSE server to get its headers, and then passing those headers into function where we will be connecting our EventSource, there will a time delay between the time the user opens the request and the server sends back its first response. We keep reference to the time the first request was made to account for that time difference later on.
1414
const startTime = Date.now();
1515

16-
http.get(headers.url, {
16+
const req = http.get(headers.url, {
1717
headers,
1818
agent: false,
19-
}, (res) => {
20-
// update info in reqResObj to reflect fact that connection was succesful
21-
reqResObj.response.headers = {...res.headers};
22-
reqResObj.connection = 'open';
23-
reqResObj.connectionType = 'SSE';
24-
// invoke function that will create an EventSource
25-
SSEController.readStream(reqResObj, event, Date.now() - startTime);
19+
});
20+
req.once('response', (res) => {
21+
// update info in reqResObj to reflect fact that connection was succesful
22+
reqResObj.response.headers = {...res.headers};
23+
reqResObj.connection = 'open';
24+
reqResObj.connectionType = 'SSE';
25+
// this is for purpose of logic in graph.jsx, which needs the entire req/res obj to have a timeReceived
26+
reqResObj.timeReceived = Date.now();
27+
// invoke function that will create an EventSource
28+
SSEController.readStream(reqResObj, event, Date.now() - startTime);
29+
req.destroy();
2630
});
2731
};
2832

@@ -43,8 +47,9 @@ SSEController.readStream = (reqResObj, event, timeDiff) => {
4347
return event.sender.send('reqResUpdate', reqResObj);
4448
};
4549
sse.onerror = (err) => {
46-
console.log('there was an error in SSEController.readStream', err)
47-
};
50+
console.log('there was an error in SSEController.readStream', err);
51+
sse.close();
52+
};
4853
};
4954

5055
module.exports = SSEController;
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
syntax = "proto3";
2-
package helloworld;
1+
// now refactored to work with testServer.js in the newer version of grpc (@grpc/grpc-js)
32

4-
service Greeter {
5-
rpc SayHello (HelloRequest) returns (HelloReply) {}
3+
syntax= "proto3";
4+
5+
service HelloWorldService {
6+
rpc GreetMe (GreetRequest) returns (GreetReply) {}
67
}
78

8-
message HelloRequest {
9+
message GreetRequest {
910
string name = 1;
1011
}
1112

12-
message HelloReply {
13-
string message = 1;
13+
message GreetReply {
14+
string reply = 1;
1415
}

grpc_mockData/protos/hw2.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ service Greeter {
77
// Sends a greeting
88
rpc SayHello (HelloRequest) returns (HelloReply) {} // single unary stream
99
rpc SayHelloNested (HelloNestedRequest) returns (HelloNestedReply) {} // nested unary stream
10+
rpc SayHellosSs (HelloRequest) returns (stream HelloReply) {}
1011
rpc SayHelloCS (stream HelloRequest) returns (HelloReply) {}
11-
rpc SayHellos (HelloRequest) returns (stream HelloReply) {}
1212
rpc SayHelloBidi (stream HelloRequest) returns (stream HelloReply) {}
1313
}
1414

grpc_mockData/server.js

Lines changed: 55 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,106 @@
11
const path = require("path");
2-
const Mali = require("mali");
3-
// consider replacing highland with normal node code for converting array to streams
2+
const fs = require("fs");
43
const hl = require("highland");
4+
const Mali = require("mali");
5+
// Mali needs the old grpc as a peer dependency so that should be installed as well
56
const grpc = require("@grpc/grpc-js");
67

8+
// consider replacing highland with normal node code for converting array to streams
9+
710
const PROTO_PATH = path.join(__dirname, "./protos/hw2.proto");
811
const HOSTPORT = "0.0.0.0:50051";
912

10-
const dataStream = [
11-
{
12-
message: "You",
13-
},
14-
{
15-
message: "Are",
16-
},
17-
{
18-
message: "doing IT",
19-
},
20-
{
21-
message: "Champ",
22-
},
23-
];
24-
25-
/**
26-
* Implements the SayHello RPC method.
27-
*/
28-
2913
// Unary stream
3014
// ctx = watch execution context
31-
function sayHello(ctx) {
32-
// create new metadata
33-
let metadata = new grpc.Metadata();
34-
metadata.set("it", "works?");
35-
metadata.set("indeed", "it do");
36-
// Watcher creates a watch execution context for the watch
37-
// The execution context provides scripts and templates with access to the watch metadata
38-
// console.log("received metadata from client request", ctx.metadata)
39-
// console.dir(ctx.metadata, { depth: 3, colors: true });
40-
// console.log(`got sayHello request name: ${ctx.req.name}`);
41-
42-
// an alias to ctx.response.res
43-
// This is set only in case of DUPLEX calls, to the the gRPC call reference itself
15+
async function sayHello(ctx) {
16+
// ctx contains both req and res objects
17+
// sets key-value pair inside ctx.response.metadata as a replacement for headers
18+
ctx.set("UNARY", "true");
4419
ctx.res = { message: "Hello " + ctx.req.name };
45-
46-
// send response header metadata object directly as an argument and that is set and sent
47-
metadata.set("UNARY", "yes");
48-
ctx.sendMetadata(metadata);
49-
50-
// console.log(`set sayHello response: ${ctx.res.message}`);
5120
}
5221
// nested Unary stream
53-
54-
function sayHelloNested(ctx) {
55-
// create new metadata
56-
let metadata = new grpc.Metadata();
57-
metadata.set("it", "works?");
58-
metadata.set("indeed", "it do");
59-
// Watcher creates a watch execution context for the watch
60-
// The execution context provides scripts and templates with access to the watch metadata
61-
// console.log("received metadata from client request", ctx.metadata)
62-
// console.dir(ctx.metadata, { depth: 3, colors: true });
63-
// console.log("ctx line 64 from server.js", ctx)
64-
22+
async function sayHelloNested(ctx) {
23+
ctx.set("UNARY", "true");
6524
// nested unary response call
66-
let firstPerson = ctx.req.firstPerson.name;
67-
let secondPerson = ctx.req.secondPerson.name;
68-
// console.log("firstPerson line 68 from server.js:", firstPerson)
25+
const firstPerson = ctx.req.firstPerson.name;
26+
const secondPerson = ctx.req.secondPerson.name;
6927
ctx.res = {
7028
serverMessage: [
7129
{ message: "Hello! " + firstPerson },
7230
{ message: "Hello! " + secondPerson },
7331
],
7432
};
75-
76-
// send response header metadata object directly as an argument and that is set and sent
77-
ctx.sendMetadata(metadata);
7833
}
7934
// Server-Side Stream
8035
// used highland library to manage asynchronous data
81-
async function sayHellos(ctx) {
82-
// create new metadata
83-
let metadata = new grpc.Metadata();
84-
metadata.set("it", "works?");
85-
metadata.set("indeed", "it do");
86-
// The execution context provides scripts and templates with access to the watch metadata
87-
// console.dir(ctx.metadata, { depth: 3, colors: true });
88-
// converts a request into strings
89-
// console.log(`got sayHellos request name:`, JSON.stringify(ctx.req, null, 4));
90-
91-
// alias for ctx.request.req
36+
async function sayHellosSs(ctx) {
37+
ctx.set("Server-side-stream", "true");
9238
// In case of UNARY and RESPONSE_STREAM calls it is simply the gRPC call's request
9339

94-
let reqMessages = { message: "hello!!! " + ctx.req.name };
95-
96-
dataStream.push(reqMessages);
97-
reqMessages = dataStream;
98-
let streamData = await hl(reqMessages);
99-
ctx.res = streamData;
100-
metadata.set("serverStream", "indeed");
101-
dataStream.pop();
102-
103-
// send response header metadata object directly as an argument and that is set and sent
104-
ctx.sendMetadata(metadata);
105-
40+
const dataStream = [
41+
{
42+
message: "You",
43+
},
44+
{
45+
message: "Are",
46+
},
47+
{
48+
message: "doing IT",
49+
},
50+
{
51+
message: "Champ",
52+
},
53+
];
54+
55+
const reqMessages = { message: "hello!!! " + ctx.req.name };
56+
// combine template with reqMessage
57+
const updatedStream = [...dataStream, reqMessages];
58+
const makeStreamData = await hl(updatedStream);
59+
ctx.res = makeStreamData;
10660
// ends server stream
10761
ctx.res.end();
10862
}
10963

11064
// Client-Side stream
111-
function sayHelloCs(ctx) {
65+
async function sayHelloCs(ctx) {
11266
// create new metadata
113-
let metadata = new grpc.Metadata();
114-
metadata.set("it", "works?");
115-
metadata.set("indeed", "it do");
116-
metadata.set("clientStream", "indubitably");
117-
// The execution context provides scripts and templates with access to the watch metadata
118-
console.dir(ctx.metadata, { depth: 3, colors: true });
119-
// console.log('got sayHelloClients')
120-
let counter = 0;
121-
let messages = [];
122-
// client streaming calls to write messages and end writing before you can get the response
67+
ctx.set("client-side-stream", "true");
68+
69+
const messages = [];
70+
12371
return new Promise((resolve, reject) => {
72+
// ctx.req is the incoming readable stream
12473
hl(ctx.req)
12574
.map((message) => {
126-
counter++;
127-
// console.log('message content',message.name)
128-
ctx.response.res = { message: "Client stream: " + message.name };
129-
messages.push(message.name);
130-
ctx.sendMetadata(metadata);
75+
console.log("parsed stream message with name key, ", message);
76+
// currently the proto file is setup to only read streams with the key "name"
77+
// other named keys will be pushed as an empty object
78+
messages.push(message);
79+
return undefined;
13180
})
132-
// returns all the elements as an array
13381
.collect()
13482
.toCallback((err, result) => {
13583
if (err) return reject(err);
136-
// console.log(`done sayHelloClients counter ${counter}`)
137-
ctx.response.res = { message: "SAYHELLOCs Client stream: " + messages };
138-
// console.log(ctx.response.res)
139-
resolve();
84+
console.log("messages ->", messages);
85+
ctx.response.res = { message: `received ${messages.length} messages` };
86+
return resolve();
14087
});
14188
});
14289
}
14390

14491
// Bi-Di stream
14592
function sayHelloBidi(ctx) {
14693
// create new metadata
147-
let metadata = new grpc.Metadata();
148-
metadata.set("it", "works?");
149-
metadata.set("indeed", "it do");
150-
// console.log("got sayHelloBidi");
94+
ctx.set("bidi-stream", "true");
95+
console.log("got sayHelloBidi");
15196
// The execution context provides scripts and templates with access to the watch metadata
15297
console.dir(ctx.metadata, { depth: 3, colors: true });
15398
let counter = 0;
154-
ctx.req.on("data", (d) => {
99+
ctx.req.on("data", (data) => {
155100
counter++;
156-
ctx.res.write({ message: "bidi stream: " + d.name });
101+
ctx.res.write({ message: "bidi stream: " + data.name });
157102
});
158-
metadata.set("bidiStream", "ohyes");
159-
ctx.sendMetadata(metadata);
103+
160104
// calls end to client before closing server
161105
ctx.req.on("end", () => {
162106
// console.log(`done sayHelloBidi counter ${counter}`);
@@ -171,7 +115,7 @@ function sayHelloBidi(ctx) {
171115
*/
172116
function main() {
173117
const app = new Mali(PROTO_PATH, "Greeter");
174-
app.use({ sayHello, sayHelloNested, sayHellos, sayHelloCs, sayHelloBidi });
118+
app.use({ sayHello, sayHelloNested, sayHellosSs, sayHelloCs, sayHelloBidi });
175119
app.start(HOSTPORT);
176120
console.log(`Greeter service running @ ${HOSTPORT}`);
177121
}

grpc_mockData/testServer.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// an example of making a test server without Mali and pure @grpc
2+
3+
const path = require("path");
4+
const grpc = require("@grpc/grpc-js");
5+
const protoLoader = require("@grpc/proto-loader");
6+
7+
// change PROTO_PATH to load a different mock proto file
8+
const PROTO_PATH = path.resolve(__dirname, "protos/helloworld.proto");
9+
const PORT = "0.0.0.0:50051";
10+
11+
const proto = protoLoader.loadSync(PROTO_PATH);
12+
const definition = grpc.loadPackageDefinition(proto);
13+
14+
const greetMe = (call, callback) => {
15+
callback(null, { reply: `Hey ${call.request.name}!` });
16+
};
17+
18+
const server = new grpc.Server();
19+
20+
server.addService(definition.HelloWorldService.service, { greetMe });
21+
22+
server.bindAsync(PORT, grpc.ServerCredentials.createInsecure(), (port) => {
23+
server.start();
24+
console.log(`grpc server running on port ${PORT}`);
25+
});

0 commit comments

Comments
 (0)