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

callback missing when use Future.wait #42

Open
himulawang opened this issue Jan 10, 2014 · 15 comments
Open

callback missing when use Future.wait #42

himulawang opened this issue Jan 10, 2014 · 15 comments
Assignees

Comments

@himulawang
Copy link

IRedisHandlerPool redisPool = new IRedisHandlerPool();

  redisPool.init(store['redis'])
  .then((_) {
    List waitList = [];
    User user = new User()..setPK(1);
    RedisClient handler = new IRedisHandlerPool().getReaderHandler(UserRedisStore.store, user);
    /*
    waitList..add(UserRedisStore.get(1, 'u:1'))
            ..add(UserRedisStore.get(2, 'u:1'));
            */
    waitList
      ..add(handler.hmget('u:1:1', user.getMapAbb().keys).then((_) => print(1)))
      ..add(handler.hmget('u:1:2', user.getMapAbb().keys).then((_) => print(2)))
      ..add(handler.hmget('u:1:3', user.getMapAbb().keys).then((_) => print(3)))
      ..add(handler.hmget('u:1:4', user.getMapAbb().keys).then((_) => print(4)))
      ..add(handler.hmget('u:1:5', user.getMapAbb().keys).then((_) => print(5)))
    ;

    return Future.wait(waitList);
  })
  .then((List list) => print(list));

output

/home/ila/ide/dart/dart-sdk/bin/dart --ignore-unrecognized-flags --debug:43375 --package-root=/home/ila/project/i_dart/packages/ /home/ila/project/i_dart/test/test.dart
Redis connected.
1
2

callback from 3 to 5 was not called

@bbss
Copy link
Contributor

bbss commented Jan 10, 2014

I'm not certain what causes this. Do you get any exceptions? I haven't done much with multiple requests yet, and am yet to look in to implementing MULTI.

@himulawang
Copy link
Author

no exception throws. just wait there.

I use MONITOR command, Seems redis has received the command.

@bbss
Copy link
Contributor

bbss commented Jan 10, 2014

test('Future.wait HMGET', () {
  async(
    client.hset('first-hash', 'some-key','some-value').then((_) => 
    client.hset('second-hash', 'some-key', 'some-value').then((_) =>
    client.hset('third-hash', 'some-key', 'some-value').then((_) {
      List waitList = [];
      waitList..add(client.hmget('first-hash', ['some-key']));
      waitList..add(client.hmget('second-hash', ['some-key']));
      waitList..add(client.hmget('third-hash', ['some-key']));

      return Future.wait(waitList);
    }).then(print))));

works for me.

@himulawang
Copy link
Author

I can't use pub get after upgrade to 1.1.0-dev.5.6 at home.
I will confirm this again at company next Monday.

Thanks

@himulawang
Copy link
Author

Hi

I use hmget to get one field, it's OK

waitList
      ..add(handler.hmget('u:1:1', ['a']).then((_) => print(1)))
      ..add(handler.hmget('u:1:2', ['a']).then((_) => print(2)))
      ..add(handler.hmget('u:1:3', ['a']).then((_) => print(3)))
    ;
/home/ila/ide/dart/dart-sdk/bin/dart --ignore-unrecognized-flags --debug:40514 --package-root=/home/ila/project/i_dart/packages/ /home/ila/project/i_dart/test/test.dart
Redis connected.
1
2
3
[null, null, null]

But if i change to multiple fields

waitList
      ..add(handler.hmget('u:1:1', ['a', 'b']).then((_) => print(1)))
      ..add(handler.hmget('u:1:2', ['a', 'b']).then((_) => print(2)))
      ..add(handler.hmget('u:1:3', ['a', 'b']).then((_) => print(3)))
    ;

callback missing

/home/ila/ide/dart/dart-sdk/bin/dart --ignore-unrecognized-flags --debug:44698 --package-root=/home/ila/project/i_dart/packages/ /home/ila/project/i_dart/test/test.dart
Redis connected.
1
2

@bbss
Copy link
Contributor

bbss commented Jan 15, 2014

I will have a look tomorrow.

@himulawang
Copy link
Author

Thanks

@ghost ghost assigned bbss Jan 20, 2014
@bbss
Copy link
Contributor

bbss commented Jan 20, 2014

I am looking into it. But also very busy so I can't make any promises for when it will be finished.

@himulawang
Copy link
Author

Not the problem, just take your time.

I use dart for fun, not for work.

Any clue show where the problem is? I'm not familar with redis protocol, but maybe I can help

@himulawang
Copy link
Author

any progress?

@bbss
Copy link
Contributor

bbss commented Feb 2, 2014

I am currently very busy as I just arrived in Shanghai for an internship, as you can see in the referenced PR I had a look today and found something that might give a clue as to what makes this bug happen (the clue being the wrong callback being fulfilled) however since I can not reproduce I am still left in the dark a bit.

What I was thinking about before is making use of darts' Zone API to get a better callstack for the errors. However I have not thought for very long about different solutions, and if this will actually work for the time-outs.

Question for @himulawang , can you run all_tests normally?

@himulawang
Copy link
Author

Haha... What a coincidence! I am Chinese from Shanghai. But today I am leaving for Japan for a trip. Back to S.H. at 02.12. C u later.

@himulawang
Copy link
Author

I can't run all_tests normally.

Two questions:

First,

.then((String value) => expect(value, equals("16.800000000000001")))

this line causes:

Uncaught Error: Expected: '16.800000000000001'
Expected: '16.800000000000001'
Actual: '16.8'
Actual: '16.8'
Which: is different. Both strings start the same, but the given value is missing the following trailing characters: 0000000000 ...
Which: is different. Both strings start the same, but the given value is missing the following trailing characters: 0000000000 ...

Second, after I block this line,

output:

/home/ila/ide/dart/dart-sdk/bin/dart --ignore-unrecognized-flags --debug:52060 --package-root=/home/ila/project/redis_client/packages/ /home/ila/project/redis_client/test/all_tests.dart

unittest-suite-wait-for-done

just wait there.

This result just like Future.wait. Callback missing.

@himulawang
Copy link
Author

I'm looking into this problem.

// source from redis_connection.dart

socket.transform(new StreamTransformer.fromHandlers(handleData: handleData, handleError:   handleError, handleDone: handleDone))
  .listen(_onRedisReply, onError: _onStreamError, onDone: _onStreamDone);

I add 3 hmget requests to waitList, and handleData function is only called 2 times.

Seems the response is missing in StreamTransformer.

also, I find another problem. Ref: #48

@himulawang
Copy link
Author

Today I find what's really happening in this problem.

When you send 2 commands in a very short time, Redis will response 2 requests with one net package.

So handleData function is invoked only once.

Send one command a time:

void handleData(List<int> data, EventSink<RedisReply> output) {
print(data)

//[42, 50, 13, 10, 36, 45, 49, 13, 10, 36, 45, 49, 13, 10]

Send two command a time:

void handleData(List<int> data, EventSink<RedisReply> output) {
print(data)

//[42, 50, 13, 10, 36, 45, 49, 13, 10, 36, 45, 49, 13, 10, 42, 50, 13, 10, 36, 45, 49, 13, 10, 36, 45, 49, 13, 10]

What we should do is create a buffer pool, a callback queue, every time a handleData is invoked, check the buffer pool, get first valid reply, cut it out, and get the first function from callback queue, call it with reply.

We can see this as ref:
https://github.com/mranney/node_redis/blob/master/index.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants