Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit a807998

Browse files
authored
move business logic from controller service to the debuglet (#194)
1 parent f7de637 commit a807998

File tree

7 files changed

+165
-224
lines changed

7 files changed

+165
-224
lines changed

src/agent/debuglet.js

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ var util = require('util');
2323
var semver = require('semver');
2424

2525
var v8debugapi = require('./v8debugapi.js');
26+
var Debuggee = require('../debuggee.js');
2627
var DebugletApi = require('../controller.js');
2728
var scanner = require('./scanner.js');
28-
var Logger = require('@google/cloud-diagnostics-common').logger;
29+
var common = require('@google/cloud-diagnostics-common');
30+
var Logger = common.logger;
2931
var StatusMessage = require('../status-message.js');
3032
var SourceMapper = require('./sourcemapper.js');
3133

@@ -72,7 +74,10 @@ function Debuglet(debug, config, logger) {
7274
this.logger_ = logger;
7375

7476
/** @private {DebugletApi} */
75-
this.debugletApi_ = new DebugletApi(this.config_, this.debug_);
77+
this.debugletApi_ = new DebugletApi(this.debug_);
78+
79+
/** @private {Debuggee} */
80+
this.debuggee_ = null;
7681

7782
/** @private {Object.<string, Breakpoint>} */
7883
this.activeBreakpointMap_ = {};
@@ -125,33 +130,86 @@ Debuglet.prototype.start = function() {
125130

126131
that.logger_.info('Unique ID for this Application: ' + id);
127132

128-
that.debugletApi_.init(id, that.logger_, function(err, project) {
133+
that.getProjectId_(function(err, project, onGCP) {
129134
if (err) {
130-
that.logger_.error('Unable to initialize the debuglet api' +
131-
' -- disabling debuglet', err);
135+
that.logger_.error('Unable to discover projectId. Please provide ' +
136+
'the projectId to be able to use the Debuglet',
137+
err);
132138
that.emit('initError', err);
133139
return;
134140
}
135141

136-
if (semver.satisfies(process.version, '5.2 || <0.12')) {
137-
// Using an unsupported version. We report an error message about the
138-
// Node.js version, but we keep on running. The idea is that the user
139-
// may miss the error message on the console. This way we can report the
140-
// error when the user tries to set a breakpoint.
141-
that.logger_.error(NODE_VERSION_MESSAGE);
142-
}
142+
that.getSourceContext_(function(err, sourceContext) {
143+
if (err) {
144+
that.logger_.warn('Unable to discover source context', err);
145+
// This is ignorable.
146+
}
143147

144-
// We can register as a debuggee now.
145-
that.running_ = true;
146-
that.project_ = project;
147-
that.scheduleRegistration_(0 /* immediately */);
148-
that.emit('started');
148+
if (semver.satisfies(process.version, '5.2 || <0.12')) {
149+
// Using an unsupported version. We report an error message about the
150+
// Node.js version, but we keep on running. The idea is that the user
151+
// may miss the error message on the console. This way we can report the
152+
// error when the user tries to set a breakpoint.
153+
that.logger_.error(NODE_VERSION_MESSAGE);
154+
}
155+
156+
// We can register as a debuggee now.
157+
that.running_ = true;
158+
that.project_ = project;
159+
that.debuggee_ = new Debuggee(
160+
project, id, that.config_.serviceContext, sourceContext,
161+
that.config_.description, null, onGCP);
162+
that.scheduleRegistration_(0 /* immediately */);
163+
that.emit('started');
164+
});
149165
});
150166
});
151167
});
152168
});
153169
};
154170

171+
172+
/**
173+
* @private
174+
*/
175+
Debuglet.prototype.getProjectId_ = function(callback) {
176+
var that = this;
177+
178+
// We need to figure out whether we are running on GCP. We can use our ability
179+
// to access the metadata service as a test for that.
180+
// TODO: change this to getProjectId in the future.
181+
common.utils.getProjectNumber(function(err, metadataProject) {
182+
// We should get an error if we are not on GCP.
183+
var onGCP = !err;
184+
185+
// We perfer to use the locally available projectId as that is least
186+
// surprising to users.
187+
var project = that.config_.projectId || process.env.GCLOUD_PROJECT ||
188+
metadataProject;
189+
190+
// We if don't have a projectId by now, we fail with an error.
191+
if (!project) {
192+
return callback(err);
193+
}
194+
return callback(null, project, onGCP);
195+
});
196+
};
197+
198+
Debuglet.prototype.getSourceContext_ =
199+
function(callback) {
200+
fs.readFile('source-context.json', 'utf8', function(err, data) {
201+
// TODO: deal with err here
202+
var sourceContext;
203+
try {
204+
sourceContext = JSON.parse(data);
205+
} catch (e) {
206+
err = 'Malformed source-context.json file:' + e;
207+
// But we keep on going.
208+
}
209+
return callback(err, sourceContext);
210+
});
211+
};
212+
155213
/**
156214
* @param {number} seconds
157215
* @private
@@ -172,7 +230,7 @@ Debuglet.prototype.scheduleRegistration_ = function(seconds) {
172230
return;
173231
}
174232

175-
that.debugletApi_.register(function(err, result) {
233+
that.debugletApi_.register(that.debuggee_, function(err, result) {
176234
if (err) {
177235
onError(err);
178236
return;
@@ -185,7 +243,7 @@ Debuglet.prototype.scheduleRegistration_ = function(seconds) {
185243
}
186244

187245
that.logger_.info('Registered as debuggee:', result.debuggee.id);
188-
246+
that.debuggee_.id = result.debuggee.id;
189247
that.emit('registered', result.debuggee.id);
190248
if (!that.fetcherActive_) {
191249
that.scheduleBreakpointFetch_(0);

src/controller.js

Lines changed: 5 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -20,116 +20,34 @@
2020
* @module debug/controller
2121
*/
2222

23-
var fs = require('fs');
2423
var assert = require('assert');
2524
var qs = require('querystring');
26-
var utils = require('@google/cloud-diagnostics-common').utils;
27-
var Debuggee = require('./debuggee.js');
2825

2926
/** @const {string} Cloud Debug API endpoint */
3027
var API = 'https://clouddebugger.googleapis.com/v2/controller';
3128

3229
/**
3330
* @constructor
3431
*/
35-
function Controller(config, debug) {
36-
config = config || {};
37-
32+
function Controller(debug) {
3833
/** @priavate {Debug} */
3934
this.debug_ = debug;
4035

41-
/** @private {string} project id */
42-
this.project_ = config.projectId || process.env.GCLOUD_PROJECT;
43-
4436
/** @private {string} debuggee id provided by the server once registered */
4537
this.debuggeeId_ = null;
4638

47-
/** @private {string} a descriptor of the current code version */
48-
this.descriptor_ = config.description;
49-
50-
/** @private {string} the service name of the current code */
51-
this.serviceName_ = config.serviceContext && config.serviceContext.service;
52-
53-
/** @private {string} the version of the current code */
54-
this.serviceVersion_ = config.serviceContext && config.serviceContext.version;
39+
/** @private {string} */
40+
this.nextWaitToken_ = null;
5541
}
5642

57-
/**
58-
* Initializes the Debuglet API. It requires a unique-id 'uniquifier' string
59-
* that identifies the version of source we have available on this client so
60-
* that it can be uniquely identified on the server.
61-
* @param {!string} uid unique identifier for the version of source loaded
62-
* in the client
63-
* @param {Logger} logger a logger
64-
* @param {!function(?Error)} callback
65-
*/
66-
Controller.prototype.init = function(uid, logger, callback) {
67-
var that = this;
68-
that.uid_ = uid;
69-
that.nextWaitToken_ = null;
70-
71-
// We need to figure out whether we are running on GCP. We can use our ability
72-
// to access the metadata service as a test for that.
73-
// TODO: change this to getProjectId in the future.
74-
utils.getProjectNumber(function(err, metadataProject) {
75-
// We should get an error if we are not on GCP.
76-
that.onGCP = !err;
77-
78-
// We prefer to use the locally available projectId as that is least
79-
// surprising to users.
80-
var project = that.project_ || metadataProject;
81-
82-
// We if don't have a projectId by now, we fail with an error.
83-
if (!project) {
84-
return callback(err);
85-
} else {
86-
that.project_ = project;
87-
}
88-
89-
// Locate the source context.
90-
fs.readFile('source-context.json', 'utf8', function(err, data) {
91-
try {
92-
that.sourceContext_ = JSON.parse(data);
93-
} catch (e) {
94-
logger.warn('Malformed source-context.json file.');
95-
// But we keep on going.
96-
}
97-
return callback(null, project);
98-
});
99-
});
100-
};
101-
102-
/**
103-
* Register to the API
104-
* @param {!function(?Error,Object=)} callback
105-
*/
106-
Controller.prototype.register = function(callback) {
107-
this.register_(null, callback);
108-
};
109-
110-
111-
/**
112-
* Register an error to the API
113-
* @param {!string} errorMessage to be reported to the Debug API
114-
*/
115-
Controller.prototype.registerError = function(message) {
116-
this.register_(message, function() {});
117-
};
118-
119-
12043
/**
12144
* Register to the API (implementation)
122-
* @param {?string} errorMessage Should be null for normal startup, and non-
123-
* null if there is a startup error that should be reported to the API
45+
*
12446
* @param {!function(?Error,Object=)} callback
12547
* @private
12648
*/
127-
Controller.prototype.register_ = function(errorMessage, callback) {
49+
Controller.prototype.register = function(debuggee, callback) {
12850
var that = this;
129-
var debuggee = new Debuggee(
130-
that.project_, that.uid_,
131-
{service: that.serviceName_, version: that.serviceVersion_},
132-
that.sourceContext_, that.descriptor_, errorMessage, that.onGCP);
13351

13452
var options = {
13553
uri: API + '/debuggees/register',

system-test/test-controller.js

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,46 @@
1717
'use strict';
1818

1919
var assert = require('assert');
20-
var Logger = require('@google/cloud-diagnostics-common').logger;
21-
var logger = Logger.create();
2220

2321
assert.ok(
2422
process.env.GCLOUD_PROJECT,
2523
'Need to have GCLOUD_PROJECT defined ' +
2624
'along with valid application default credentials to be able to run this ' +
2725
'test');
28-
var config = {};
2926

30-
var debug = require('../')(config);
31-
var DebugletApi = require('../src/controller.js');
27+
var Controller = require('../src/controller.js');
28+
var Debuggee = require('../src/debuggee.js');
29+
var debug = require('../')();
3230

33-
describe('Debugletapi', function() {
31+
32+
describe('Controller', function() {
3433

3534
it('should register successfully', function(done) {
36-
var debugletApi = new DebugletApi({}, debug);
37-
debugletApi.init('test-uid-1', logger, function(err) {
38-
assert.ifError(err, 'init should complete successfully');
35+
var controller = new Controller(debug);
36+
var debuggee =
37+
new Debuggee(process.env.GCLOUD_PROJECT, 'test-uid-' + Date.now());
3938

40-
debugletApi.register(function(err, body) {
41-
assert.ifError(err, 'should be able to register successfull');
42-
assert.ok(body);
43-
assert.ok(body.debuggee);
44-
assert.ok(body.debuggee.id);
45-
done();
46-
});
39+
controller.register(debuggee, function(err, body) {
40+
assert.ifError(err, 'should be able to register successfull');
41+
assert.ok(body);
42+
assert.ok(body.debuggee);
43+
assert.ok(body.debuggee.id);
44+
done();
4745
});
4846
});
4947

5048
it('should list breakpoints', function(done) {
51-
var debugletApi = new DebugletApi({}, debug);
52-
debugletApi.init('test-uid-2', logger, function(err) {
53-
assert.ifError(err, 'init should complete successfully');
49+
var controller = new Controller(debug);
50+
var debuggee =
51+
new Debuggee(process.env.GCLOUD_PROJECT, 'test-uid-' + Date.now());
52+
controller.register(debuggee, function(err, body) {
53+
assert.ifError(err, 'should be able to register successfull');
5454

55-
debugletApi.register(function(err, body) {
56-
assert.ifError(err, 'should be able to register successfull');
57-
58-
debugletApi.listBreakpoints(function(err, response, body) {
59-
assert.ifError(err, 'should successfully list breakpoints');
60-
assert.ok(body);
61-
assert.ok(body.nextWaitToken);
62-
done();
63-
});
55+
controller.listBreakpoints(function(err, response, body) {
56+
assert.ifError(err, 'should successfully list breakpoints');
57+
assert.ok(body);
58+
assert.ok(body.nextWaitToken);
59+
done();
6460
});
6561
});
6662
});

test/e2e/test-breakpoints.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,12 @@ if (cluster.isMaster) {
283283
setTimeout(function() {
284284
assert.ok(debug.private_, 'debuglet has initialized');
285285
var debuglet = debug.private_;
286-
assert.ok(debuglet.debugletApi_, 'debuglet api is active');
287-
var api = debuglet.debugletApi_;
288-
assert.ok(api.uid_, 'debuglet provided unique id');
289-
assert.ok(api.debuggeeId_, 'debuglet has registered');
286+
var debuggee = debuglet.debuggee_;
287+
assert.ok(debuggee, 'should create debuggee');
288+
assert.ok(debuggee.project, 'debuggee should have a project');
289+
assert.ok(debuggee.id, 'debuggee should have registered');
290290
// The parent process needs to know the debuggeeId and project.
291-
process.send([api.debuggeeId_, api.project_]);
291+
process.send([debuggee.id, debuggee.project]);
292292
setInterval(fib.bind(null, 12), 2000);
293293
}, 7000);
294294

test/e2e/test-log-throttling.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,12 @@ if (cluster.isMaster) {
212212
setTimeout(function() {
213213
assert.ok(debug.private_, 'debuglet has initialized');
214214
var debuglet = debug.private_;
215-
assert.ok(debuglet.debugletApi_, 'debuglet api is active');
216-
var api = debuglet.debugletApi_;
217-
assert.ok(api.uid_, 'debuglet provided unique id');
218-
assert.ok(api.debuggeeId_, 'debuglet has registered');
219-
process.send([api.debuggeeId_, api.project_]);
215+
var debuggee = debuglet.debuggee_;
216+
assert.ok(debuggee, 'should create debuggee');
217+
assert.ok(debuggee.project, 'debuggee should have a project');
218+
assert.ok(debuggee.id, 'debuggee should have registered');
219+
// The parent process needs to know the debuggeeId and project.
220+
process.send([debuggee.id, debuggee.project]);
220221
setInterval(fib.bind(null, 12), 500);
221222
}, 7000);
222223
}

0 commit comments

Comments
 (0)