Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Dart, how to properly return an HttpResponse using Future's

I am attempting to create a very simple http server that does one thing. Upon receiving an HttpRequest, it runs a query on the local database server, and returns a string based on that query.

I am learning Dart, and I am having trouble grasping Futures. I thought I understood them, but this example leads me to believe I really have no idea how they work. So, not only am I looking for a solution to this problem, but any pointers I will gladly accept as well.

Note: This code is a very primitive example of what I have been trying to accomplish, and for the sake of reaching out to the Stackoverflow community, I have shortened / simplified it as much as possible, while keeping the problem intact.

Here is my server.dart code

import 'dart:io';
import 'package:sqljocky/sqljocky.dart';


final connection = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', password: null, db: 'server1');

main() {

  HttpServer.bind(InternetAddress.ANY_IP_V4, 9090)..then((server) {
    print("serving generic database query on localhost:9090");
    server.listen((request) {
      if (request.method == "GET") {
        request.response.write(getResults());
        request.response.close();
      }
      else {
        request.response.statusCode = HttpStatus.BAD_REQUEST;
      }
    });
  });
}


String getResults() {

  StringBuffer sb = new StringBuffer();
  sb.write("START--");
  connection.query("select name, email, zkey from users")
      ..then((results) {
    results.forEach((row) {
      sb.write(row.toString());
      print(row.toString());
    });
  });

  sb.write("--END");
  print(sb.toString());

  return sb.toString();
}

So if I send a request to this server it returns "START----END". The server prints out the expected query result, and then prints out "START----END". This leads me to believe that my request response is closing and returning before the query result is done processing.

So whether I curl localhost:9090/asdf or actually build a client http request sender, I do not get the response I am expecting... which is a database query result.

Thanks in advance

like image 701
jabgibson Avatar asked Aug 06 '14 03:08

jabgibson


1 Answers

That "START----END" is printed 'out of order' is a behavior of futures that is confusing to most developers in the beginning.
A call like connection.query() which returns a future is not executed immediately but enlisted in a queue for later execution. The current thread of execution is continued until finished and then the queue is processed one after another.

What doesn't work in your code is that you do an async call connection.query() and continue as if it was a sync call. That does never work in Dart. When you start an async execution you cant go back to sync. (as far as I know the planned async/await should solve this).

More details at dartlang.org The Event Loop and Dart

EDIT tested code

import 'dart:io';
import 'package:sqljocky/sqljocky.dart';

final connection = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', password: null, db: 'server1');

main() {    
  HttpServer.bind(InternetAddress.ANY_IP_V4, 9090)..then((server) {
    print("serving generic database query on localhost:9090");
    server.listen((request) {
      if (request.method == "GET") {
        getResults()
        .then((result) { 
          print('Result: $result'); 
          request.response.write(result);
          request.response.close();
        });
      }
      else {
        request.response.statusCode = HttpStatus.BAD_REQUEST;
      }
    });
  });
}

Future<String> getResults() { 

  StringBuffer sb = new StringBuffer();
  sb.write("START--");
  return connection.query("select name, email, zkey from users") 
  .then((Result results) => results.toList())
  .then((list) {
    list.forEach((row) {
      sb.write(row.toString());
    });
    sb.write("--END");
  })
  .then((_) => sb.toString());
}

See also Gregs answer on this question how to read SqlJocky results sqljocky querying database synchronously

like image 112
Günter Zöchbauer Avatar answered Oct 09 '22 08:10

Günter Zöchbauer