Repository navigation
Return Jobs/Operations directly from the method that starts them #1306
Description
Activity
- addedapi: computeIssues related to the Compute Engine API.Issues related to the Compute Engine API.api: bigqueryIssues related to the BigQuery API.Issues related to the BigQuery API.
on May 11, 2016 I think if the operation/job was responsible for creating something (like a VM) that the created VM would be emitted via
complete.I forgot about the previously existing
runningevent, perhapscreated(or similar) would be better suited.compute.createVM('vm-name') .on('error', function(err) {}) .on('created', function(apiResponse) {}) .on('running', function(operationMetadata) {}) .on('complete', function(vm, operationMetadata) {});
edit: created is bad too, haha, my naming abilities are failing me today
stephenplusplus commented
on May 11, 2016 ContributorAuthorMore actionscreatedandrunningfeel a little too similar, maybe we should just not return the originalapiResponse. If an error occurred with thecreateVMAPI call, then the apiResponse is already included there. The initial state of the operation shouldn't be vital... but it theoretically should be available fromoperation.metadataat some point:var operation = compute.createVM('vm-name') .on('error', function(err) {}) // the "POST /vm-name" call failed OR the operation failed .on('running', function() {}) // arg removed. `operation.metadata` can be checked for the status .on('complete', function(vm) {}); // took out `operationMetadata`. they can check `operation.metadata` for the status
I agree,
createdwas a bad choice, I think the point I'm trying to convey is that we could easily just emit an event specifically to capture the apiResponse. Some other possible options could bequeued,operation-created,started, etc..stephenplusplus commented
on May 12, 2016 ContributorAuthorMore actionsI know, I think it's just unnecessary. Please let me know what you think about the example in the last post. I've removed all metadata like arguments from the events themselves.
That could work, I'm not a huge fan of making the initial apiResponse completely inaccessible though.
Unrelated: Does this have any effect on
autoCreateapis?stephenplusplus commented
on May 12, 2016 ContributorAuthorMore actionsThat could work, I'm not a huge fan of making the initial apiResponse completely inaccessible though.
If it's an error,
apiResponseis accessible from theApiError. If it succeeds, then the response is the initial Job/Operation metadata, which is available from the returned object:var operation = zone.createVM('vm-name'); operation.metadata === apiResponse; // obviously not immediately, we emit `running` but no potentially stale "status" of the operation
Unrelated: Does this have any effect on autoCreate apis?
Hmm, good thought. Let's see...
var operation = vm.get({ autoCreate: true }); // the "GET /vm-name" call failed OR the "POST /vm-name" call failed OR the operation failed operation.on('error', function(err) {}); // The VM is being created -- not emitted unless we have to create it operation.on('running', function() {}); // The VM was either created or it already existed. Return the object here operation.on('complete', function(vm) {});
Wdyt?
stephenplusplus commented
on May 12, 2016 ContributorAuthorMore actionsIt does seem like we're stepping on the toes of the future support of Promises... should we wait to tackle this then?
Probably a good idea
- addedstatus: blockedResolving the issue is dependent on other work.Resolving the issue is dependent on other work.
on May 12, 2016 stephenplusplus commented
on Oct 10, 2016 ContributorAuthorMore actions@callmehiphop do you think we should support this in 1.0 or wait until after, at the cost of breaking the API and forcing a 2.0?
I like the idea of supporting it in 1.0 personally, we're already going to be breaking quite a bit with promises, so it might be a good idea to do it now and not make users have to refactor their code a second time when we do get around to it.
Reacted by Stephen11 remaining items
stephenplusplus commented
on Oct 11, 2016 ContributorAuthorMore actions@jjgeewax's examples start the timer every time
That doesn't sound right, but let me know if I'm mistaken:
Zone.prototype.createVM = function() { console.log('making the request...') return this.request(...) // ... } var operation = zone.createVM(); // => "making the request..."
So if the request can be made when someone calls
zone.createVM(), we just need to know when events are registered, so we know what to do next (not sure if this is possible):// Calling this method makes the API request to create an instance var operation = zone.createVM(); // Returns the API response from the VM being created // The operation hasn't started an interval operation.on('response', function(apiResponse) {}); // Now the operation will start an interval // This callback executes when the operation is complete operation.then(function() { // VM created });
Basically, if it's possible to distinguish between when a user registers an event handler on
responsevs athenhandler, we should be able to make this work... maybe?If not, separate methods are fine with me.
On trying to watch for
.then: the promise creator is decoupled from the promise consumer(s)—it doesn't know anything about when or how the promise will be consumed. We can't have the promise creator trying to couple itself to the consumer. We'd have to re-implementPromise#then.On trying to watch for
.on: Similar argument as with promise, We'd have to change the implementation ofEventEmitter#onin order to hook into it and couple the creator to the consumer. My insides hurt thinking about this.// Calling this method makes the API request to create an instance
var operation = zone.createVM();I don't see how
Zone#createVM(orSpeech#startRecognition) can be synchronous, as they're making an API call. We have to wait for the API to complete to get the operation id in order to even be able to do.on('complete', ...).@callmehiphop's examples, slightly amended:
// user just wants to enqueue the operation compute.startCreateVM(); // user cares about the operation compute.startCreateVM().then((operation) => { console.log(operation.id); // id was provided by response from initial API call operation .on('error', (err) => { // error during operation, i.e. server error }) .on('complete', (vm) => {}); }, (err) => { // failed to start operation, i.e. bad argument }); // user just cares about the result of the operation compute.createVM().then((vm) => { ... }, (err) => { // err could be from initial API call, e.g. failed to create operation // or err could have happened during the operation itself });
stephenplusplus commented
on Oct 12, 2016 ContributorAuthorMore actionsI don't see how Zone#createVM (or Speech#startRecognition) can be synchronous, as they're making an API call.
It wouldn't be synchronous, but using another example, what happens with a method that doesn't use an operation:
Zone.prototype.getVMs = function() { return this.request(...); } var getVMsPromise = zone.getVMs() // was a request made, even though I didn't register a `then`?
stephenplusplus commented
on Oct 12, 2016 ContributorAuthorMore actionsRegarding your first two points, I agree that offering dual-functionality from this single method doesn't sound great, but wanted to see if a solution is in fact available, given @jgeewax's original proposal. From a technical standpoint, it might not be as sickening as overriding
.thenand.on, if there is an underlying event emitter on a Promise, i.e.:Zone.prototype.createVM = function() { var requestPromise = this.request(...) requestPromise.on('newListener', function (name) { if (name === 'then') // resolve with completed operation else if (name === 'response') // resolve with api response }) return requestPromise }
Just putting this out there in case you guys know if that's how it works. If not, I definitely don't want to override
then,on, etc.stephenplusplus commented
on Oct 14, 2016 ContributorAuthorMore actionsAfter some thinking, a more simple and obvious solution presented itself, implemented in #1689, which fits in nicely with the chained nature of promises. Feel free to re-open this issue if more discussion is needed.
- added a commit that references this issue
on Mar 18, 2026 - added a commit that references this issue
on Mar 27, 2026
RE: #1294 (comment)
Blocked
Let's wait for our support of promises to engineer this.
Before:
After:
@callmehiphop What should we do in these situations (regarding the second argument,
vm):Emit
vmwithrunning?... or is that getting weird?