Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BE-834 Fix memory leak issue of sync process #206

Merged
merged 3 commits into from
Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ first-network/channel-artifacts/*
tmp/wallet/*
wallet/*
*.swp
package-lock.json
# package-lock.json
ssl-certs/*.pem
ssl-certs/*.csr
0
Expand Down
8 changes: 8 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"require": "./node_modules/ts-node/register",
"watch-extensions": "ts",
"recursive": true,
"spec": ["./app/test/**/*.test.ts"],
"timeout": 10000,
"extension": ["ts"]
}
18 changes: 18 additions & 0 deletions .nycrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "@istanbuljs/nyc-config-typescript",
"require": ["ts-node/register"],
"extension": [".ts"],
"reporter": ["lcov", "text-summary"],
"sourceMap": true,
"instrument": true,
"temp-dir": "app/test/.nyc_output",
"report-dir": "app/test/coverage",
"all": true,
"include": ["app"],
"exclude": ["**/e2e-test", "app/test"],
"check-coverage": false,
"branches": 80,
"lines": 80,
"functions": 80,
"statements": 80
}
116 changes: 74 additions & 42 deletions app/platform/fabric/gateway/FabricGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as fabprotos from 'fabric-protos';
import { Discoverer, DiscoveryService } from 'fabric-common';
import concat from 'lodash/concat';
import * as path from 'path';
import * as fs from 'fs';
import { helper } from '../../../common/helper';
import { explorerError } from '../../../common/ExplorerMessage';
import { ExplorerError } from '../../../common/ExplorerError';
Expand All @@ -32,6 +31,8 @@ export class FabricGateway {
FSWALLET: string;
enableAuthentication: boolean;
asLocalhost: boolean;
ds: DiscoveryService;
dsTargets: Discoverer[];

/**
* Creates an instance of FabricGateway.
Expand All @@ -52,6 +53,8 @@ export class FabricGateway {
this.FSWALLET = null;
this.enableAuthentication = false;
this.asLocalhost = false;
this.ds = null;
this.dsTargets = [];
}

async initialize() {
Expand Down Expand Up @@ -373,61 +376,90 @@ export class FabricGateway {
}
}

async getDiscoveryResult(channelName) {
async setupDiscoveryRequest(channelName) {
try {
const network = await this.gateway.getNetwork(channelName);
const channel = network.getChannel();
const ds = new DiscoveryService('be discovery service', channel);
this.ds = new DiscoveryService('be discovery service', channel);

const client = new Client('discovery client');
if (this.clientTlsIdentity) {
logger.info('client TLS enabled');
client.setTlsClientCertAndKey(
this.clientTlsIdentity.credentials.certificate,
this.clientTlsIdentity.credentials.privateKey
);
} else {
client.setTlsClientCertAndKey();
}
const idx = this.gateway.identityContext;
// do the three steps
this.ds.build(idx);
this.ds.sign(idx);
} catch (error) {
logger.error('Failed to set up discovery service for channel', error);
this.ds = null;
}
}

const mspID = this.config.client.organization;
const targets = [];
for (const peer of this.config.organizations[mspID].peers) {
const discoverer = new Discoverer(`be discoverer ${peer}`, client, mspID);
const url = this.config.peers[peer].url;
const pem = this.fabricConfig.getPeerTlsCACertsPem(peer);
let grpcOpt = {};
if ('grpcOptions' in this.config.peers[peer]) {
grpcOpt = this.config.peers[peer].grpcOptions;
}
const peer_endpoint = client.newEndpoint(
Object.assign(grpcOpt, {
url: url,
pem: pem
})
);
await discoverer.connect(peer_endpoint);
targets.push(discoverer);
async getDiscoveryServiceTarget() {
const client = new Client('discovery client');
if (this.clientTlsIdentity) {
logger.info('client TLS enabled');
client.setTlsClientCertAndKey(
this.clientTlsIdentity.credentials.certificate,
this.clientTlsIdentity.credentials.privateKey
);
} else {
client.setTlsClientCertAndKey();
}

const targets: Discoverer[] = [];
const mspID = this.config.client.organization;
for (const peer of this.config.organizations[mspID].peers) {
const discoverer = new Discoverer(`be discoverer ${peer}`, client, mspID);
const url = this.config.peers[peer].url;
const pem = this.fabricConfig.getPeerTlsCACertsPem(peer);
let grpcOpt = {};
if ('grpcOptions' in this.config.peers[peer]) {
grpcOpt = this.config.peers[peer].grpcOptions;
}
const peer_endpoint = client.newEndpoint(
Object.assign(grpcOpt, {
url: url,
pem: pem
})
);
await discoverer.connect(peer_endpoint);
targets.push(discoverer);
}
return targets;
}

const idx = this.gateway.identityContext;
// do the three steps
ds.build(idx);
ds.sign(idx);
await ds.send({
async sendDiscoveryRequest() {
try {
await this.ds.send({
asLocalhost: this.asLocalhost,
requestTimeout: 5000,
refreshAge: 15000,
targets: targets
targets: this.dsTargets
});
logger.info('Succeeded to send discovery request');

const result = await ds.getDiscoveryResults(true);
const result = await this.ds.getDiscoveryResults(true);
return result;
} catch (error) {
logger.error(
`Failed to get discovery result from channel ${channelName} : `,
error
);
logger.error('Failed to send discovery request for channel', error);
this.ds.close();
this.ds = null;
}
return null;
}

async getDiscoveryResult(channelName) {
if (!this.ds) {
await this.setupDiscoveryRequest(channelName);
}

if (!this.dsTargets.length) {
this.dsTargets = await this.getDiscoveryServiceTarget();
}

if (this.ds && this.dsTargets.length) {
const result = await this.sendDiscoveryRequest();
return result;
}

return null;
}
}
Loading