4

A controller has $http that calls an api backend on Flask. I have some basic authentication and crossdomain is set. The first time it enters the cpuListCtrl controller the $http calls takes cca. ~14sec. The next time i visited the controller in angular it takes just 23ms. But every time i press the browsers refresh, back to ~14sec. Direct api call from browser also takes just 23ms. So my question is my does it takes so long, did i miss something, or where specific should i look?

EDIT: updated the code to reflect recent changes:

  var app = angular.module('RecycleApp', ['ngRoute', 'appControllers']);
    app.config(['$httpProvider', function($httpProvider) {
     $httpProvider.defaults.useXDomain = true;
     delete $httpProvider.defaults.headers.common['X-Requested-With'];
   }
  ]);

  app.config(['$routeProvider', function($routeProvider){
  $routeProvider
    .when("/cpu", {
        templateUrl:'static/js/partials/cpu.html',
        controller:'cpuCtrl'
    })
  }]);

  var appControllers = angular.module('appControllers', []);

  appControllers.controller('cpuCtrl', ['$scope','$http',
function($scope,$http){
    $http({
        url: 'http://SOME_IP/api/v1/cpus',
        method: 'POST',
        data: JSON.stringify({"latitude":46.1948436, "longitude":15.2000873}),
        headers: {"Content-Type":"application/json"}
    })
    .success(function(data,status,headers,config){
        console.log(data.list);
        $scope.cpus = data.list;
    })
    .error(function(data,status,headers,config){
        console.log("something went wrong.");   
    })

 }]);

Server side:

@app.route('/api/v1/cpus', methods=["GET"])
@cross_origin(origins='*', headers=("Content-Type"))
def get_cpu_list():
    result = session.query(RecycleReUseCenter)\
            .options(load_only("Id", "CpuName"))\
            .all()
    return list_json(result)

@app.route("/api/v1/cpus", methods=["POST"])
@cross_origin(origins='*', headers=("Content-Type"))
def get_cpu_list_with_locations():
    content = request.get_json(force=True)
    given_latitude = content['latitude']
    given_longitude = content['longitude']

    result = RecycleReUseCenter.get_all_with_distance(given_latitude, given_longitude)
    return list_json(result)
zPrima
  • 687
  • 7
  • 20
  • 1
    There are a million things that it could be, and we don't have enough information to answer. You should look at the chrome developer tools and your backend API logs for the request and see where it's spending it's time. – John Ledbetter Jan 24 '14 at 17:52
  • chrome tools shows its waiting that long, the flask log registers the call to him only at the last miliseconds, i have a feeling that the $http waits and after some time it executes... i implemented it with $resource and it was the same. – zPrima Jan 24 '14 at 17:58
  • This is probably related to webapi warm up check this out: http://weblog.west-wind.com/posts/2012/Sep/04/ASPNET-Frameworks-and-Raw-Throughput-Performance – Dalorzo Jan 24 '14 at 17:59
  • Nah, running the default server that comes with Flask, if i put the direct api call into the browser, it takes 23ms to finish the job. – zPrima Jan 24 '14 at 18:07
  • Is the flask server on heroku? – alonisser Jan 24 '14 at 18:44
  • its local, as is angular, seems the problem is with CORS – zPrima Jan 24 '14 at 18:57
  • Flask/Werkzeug is single threaded by default. Putting threaded=True in run should immediately solve this. Or just use a WSGI server. – yeaske Jun 20 '17 at 16:02

3 Answers3

0

Do you know for sure when does the http call starts? The angular app may be stuck somewhere else, and getting to the http call only in the last second. For example - in the config you are using a "token" where do you get it from? in many angular app this is fetched from some oauth service, in a seperete call. Your slow call won't start until http is configured. After token is there, the next calls would be faster since we got the token already.

To limit some guessing you can use a proxy tool like charles - or deflect.io chrome extension to watch all the out going http calls and figure this out

alonisser
  • 10,004
  • 16
  • 71
  • 123
  • I eliminated the need for a token, just basic CORS, with Allow-Origin * and Allow-Header Content-Type. The OPTIONS call takes 20sec, the POST that follows a couple of ms. Thinking that the problem may be on the how the default flask server handles these things. – zPrima Jan 26 '14 at 18:25
  • If the problem is the OPTIONS call - did you try with another browser? (I think firefox won't do that). Also if the server on heroku? – alonisser Jan 27 '14 at 08:44
  • nah, its the same in firefox, after digging into response of the OPOTIONS call i saw that it returns the same thing as a GET request would (a list of json objects). After that the POST call gets called which returns the result i want. Is there any way to eliminate the extra OPTIONS call, or is that how it is with CORS? Server is virtual, running on a server machine on local network. – zPrima Jan 27 '14 at 20:47
  • yeah the OPTIONS this is a CORS [issue](http://stackoverflow.com/questions/12111936/angularjs-performs-an-options-http-request-for-a-cross-origin-resource). can be fixed by some server setup (see the link for details) – alonisser Jan 28 '14 at 07:46
  • i changed some settings like keep alive on, timeout and maxrequesttimeout, seems to be ok now. – zPrima Jan 29 '14 at 11:36
  • @zPrima can you show the code for these new settings that fixed it? Was it on server or frontend settings? I would love to see it :) – Paul Jun 11 '14 at 05:11
  • yeah, some time has passed since then, don't have these settings anymore. i updated to the latest angualrjs 1.2.x and reinstalled flask with python 3.3.5 on wamp 64bit, don't have to set any of previous settings now, it just works. – zPrima Jun 11 '14 at 06:44
0

I have recently had the same problem, and found that the delay oddly enough actually seems to be on the Flask end, but only happens when using an Angular app running in Chrome. This answer from the python stackexchange forum is the best one I have seen - https://stackoverflow.com/a/25835028/1521331 - it provides a 'solution' of sorts, if not an explanation for this mystery!

Community
  • 1
  • 1
Janak Mayer
  • 116
  • 1
  • 5
0

I was having the same problem, and none of the above worked for me. Here's what did:

Slow Requests on Local Flask Server

Effectively, certain browsers will attempt to access IPv6 sockets before IPv4. After commenting out the offending lines in /etc/hosts and restarting apache the problem was fixed.

Community
  • 1
  • 1
nmarsh
  • 144
  • 7