Skip to content

Commit

Permalink
BE-834 Fix memory leak issue of sync process (hyperledger-labs#206)
Browse files Browse the repository at this point in the history
* BE-834 Fix memory leak issue in the setup of DS

Changed to keep a discovery service instance after initializing it at
the boot phase.

Signed-off-by: Atsushi Neki <[email protected]>

* BE-834 Add unit test for the fix of memory leak issue

Signed-off-by: Atsushi Neki <[email protected]>

* Add code coverage for unit test

Signed-off-by: Atsushi Neki <[email protected]>
  • Loading branch information
nekia authored Dec 11, 2020
1 parent d3b8b97 commit ed36c28
Show file tree
Hide file tree
Showing 68 changed files with 2,526 additions and 7,484 deletions.
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

0 comments on commit ed36c28

Please sign in to comment.