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

feat(callback): Add Observable.fromCallback #729

Closed
wants to merge 1 commit into from

Conversation

SomeKittens
Copy link
Contributor

No description provided.

@SomeKittens
Copy link
Contributor Author

Ran into an odd situation. With the additional tests included in this PR, I get this error:

Failures:
1) Observable.prototype.bufferWhen should NOT handle hot inner empty
  Message:
    RangeError: Maximum call stack size exceeded
  Stack:
    RangeError: Maximum call stack size exceeded

removing any one of the tests (or any test in from-promise-spec.js, but not debouncetime-spec.js, the other two I tried) results in bufferWhen passing.

I'm guessing it's a race condition somewhere, with the extra tests, the tests are running long enough to trigger the overflow. Changing the test to the following results in it passing though I'm not sure if it invalidates the test:

  // bufferWhen is not supposed to handle a factory that returns always empty
  // closing Observables, because doing such would constantly recreate a new
  // buffer in a synchronous infinite loop until the stack overflows. This also
  // happens with buffer in RxJS 4.
  it('should NOT handle hot inner empty', function (done) {
    var source = Observable.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    var closing = Observable.empty();
    var TOO_MANY_INVOCATIONS = 30;

    var invoked = 0;
    source
      .bufferWhen(function () {
        if (invoked <= TOO_MANY_INVOCATIONS) {
          return closing;
        }
        return Observable.interval(100);
      })
      .subscribe(function (val) {
        invoked++;
        if (invoked > TOO_MANY_INVOCATIONS) {
          return done();
        }
        expect(Array.isArray(val)).toBe(true);
        expect(val.length).toBe(0);
      }, null, null);
  });

@SomeKittens
Copy link
Contributor Author

Ah, missed linting, fixing that now.

import {tryCatch} from '../util/tryCatch';
import {errorObject} from '../util/errorObject';

export class CallbackObservable<T> extends Observable<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about align class name to observable, such as Observable.fromEvent has implementation named FromEventObservable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to mimic PromiseObservable with regards to that sort of thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, just noticed that too.

@SomeKittens
Copy link
Contributor Author

Tried to match things to what's going on in PromiseObservable.ts with regards to scalar things and schedulers. Not 100% confident, I'd appreciate it if you'd go over that section with a fine-tooth comb.

};
}
} else {
let subscription = new Subscription();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this variable seems could be const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@kwonoj
Copy link
Member

kwonoj commented Nov 15, 2015

Appreciate for effort, I didn't even noticed fromCallback is yet implemented :) I'll try to add some comment.

@SomeKittens SomeKittens force-pushed the from-callback branch 2 times, most recently from 2a28cbe to c1e30fe Compare November 15, 2015 18:36
@SomeKittens
Copy link
Contributor Author

Hello! Any update on this?

@kwonoj
Copy link
Member

kwonoj commented Nov 18, 2015

I am generally ok with current changes, but would like to ask @Blesh 's opinion also may have better suggestions than me. Also, testing failure you've mentioned makes this as bit blocked, since those issue need to be addressed and resolved to correctly merge this PR.

@SomeKittens
Copy link
Contributor Author

Yep, willing to do whatever's needed to get those tests passing but I'm stumped. I can put in the fix I mentioned if you or @Blesh are ok with it (not sure if it breaks the spirit of the test).

@kwonoj
Copy link
Member

kwonoj commented Nov 18, 2015

Just rough guess, maybe test cases observable is not unsubscribed?

could possibly revise test case like below, what do you think @staltz ?

source.bufferWhen(function () { return closing; })
      .takeWhile(function(val, index) {
        return index < TOO_MANY_INVOCATIONS;
      })
      .subscribe(function (val) {
        expect(Array.isArray(val)).toBe(true);
        expect(val.length).toBe(0);
      }, done.fail, done);

@benlesh
Copy link
Member

benlesh commented Nov 18, 2015

Sometimes async tests in jasmine get corrupt somehow. I'm not entirely sure what causes it, but I've seen it before. Anecdotally, I've pulled the PR down locally and it runs fine.

However, I don't think this PR matches with what fromCallback did previously. I'll add some comments to the commits.

@benlesh
Copy link
Member

benlesh commented Nov 18, 2015

However, I don't think this PR matches with what fromCallback did previously.

... ignore that, I was just confused by one of the tests. Perhaps the test just needs refactored a little for readability.

@SomeKittens
Copy link
Contributor Author

@Blesh Fixed, test is more specific now.

};
}

constructor(private callbackFunc: Function, private ctx, private selector, private args: any[], public scheduler: Scheduler = immediate) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please give a newline for each argument? Like we do elsewhere, see e.g. https://github.com/ReactiveX/RxJS/blob/master/src/observables/IteratorObservable.ts#L61-L65

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@staltz
Copy link
Member

staltz commented Nov 19, 2015

Thanks @SomeKittens for this PR.

@SomeKittens
Copy link
Contributor Author

@staltz as to the complexity of _subscribe, I based this off https://github.com/ReactiveX/RxJS/blob/master/src/observables/PromiseObservable.ts

Each path is slightly unique, not sure what to target for refactor.

@SomeKittens
Copy link
Contributor Author

(also rebased @kwonoj's test fixes into this branch)

expect(err.message).toBe('Yikes!');
done();
},
null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This null here should also be done.fail

@SomeKittens
Copy link
Contributor Author

@staltz fixed missed null.

@staltz
Copy link
Member

staltz commented Nov 20, 2015

Great

@SomeKittens
Copy link
Contributor Author

Anything else?

subscriber.complete();
} else {
handler = (...innerArgs) => {
let results;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can move let results down to where it's being used on line 52

@benlesh
Copy link
Member

benlesh commented Nov 20, 2015

Disregard my comments. I never use this creation method.

Frankly I think this is really a weird experience, and I dislike how it works. Every other fromWhatever method returns an Observable, not a function that returns a stateful observable.

@benlesh
Copy link
Member

benlesh commented Nov 20, 2015

This LGTM. However, I'm not sure about including it in Core.

@SomeKittens
Copy link
Contributor Author

@Blesh Agreed on it being weird, but that's how it works in Rx4 (and for that matter, Bluebird and the whole promise spectrum). I'm open to updating the signature to return an observable, possibly passing in the callback args.

@SomeKittens
Copy link
Contributor Author

Sorry to continue pinging everyone, but is there anything else here that needs fixing? (or is the holdup deciding if this should be in core or not?)

@benlesh
Copy link
Member

benlesh commented Nov 25, 2015

or is the holdup deciding if this should be in core or not?)

The hold up is mostly just me being too busy. :) Reviewing this now.

@benlesh
Copy link
Member

benlesh commented Nov 25, 2015

Merged as of f6cebb6, with some minor lint fixes. Thanks @SomeKittens! This was a nice PR.

@SomeKittens
Copy link
Contributor Author

The hold up is mostly just me being too busy. :) Reviewing this now.

It happens, especially around this time of year. Thanks!

@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants