0

Connectivity functions

I was adding some events to my widget to test the connectivity and the network status, when i came to use the function KONtx.application.isPhysicalNetworkDown() it says "isPhysicalNetworkDown" is not a function and stops the compiling. Has this method been changed?
CODE
	

send: function(url,func,info) {
if (KONtx.application.isPhysicalNetworkDown()) {
log("the network is down!");
return;
}

var request = new URL();

request.location = url;
request.func = func;

request.info = info;


request.fetchAsync(Network.finish);

},

by
16 Replies
  • It is just a value, not a method.

    CODE
    var status = (KONtx.application.isPhysicalNetworkDown) ? "Network Down" : "Network Up"
    print(status);
    0
  • QUOTE (WidgetRealm @ Nov 8 2010, 05:36 AM) <{POST_SNAPBACK}>
    It is just a value, not a method.

    CODE
    var status = (KONtx.application.isPhysicalNetworkDown) ? "Network Down" : "Network Up"
    print(status);

    Yes, it's defined as a getter, but since it returns a function it needs to be invoked with the parens operater. Your code is only checking for its existence, not the actual state of the physical network. So, if the framework has included this getter, the above code will always report that the network is down (and vice versa).

    - Ben
    0
  • Nice to know since the example on the FAQ is wrong then, i lost hours trying to figure it out since it seems to be one of the requirement of the Acceptance Criteria
    CODE
    function callAPI(url, callback) {
    if (KONtx.application.isPhysicalNetworkDown()) {
    log("the network is down!");
    return;
    }
    var request = new URL();
    request.callback = callback;
    request.location = url;
    KONtx.utility.WaitIndicator.up();
    request.fetchAsync(function (u) {
    KONtx.utility.WaitIndicator.down();
    if (u.response == 200){
    myWidget.application.setNetworkRequestFailed(false);
    u.callback(u.result);
    } else {
    myWidget.application.setNetworkRequestFailed(true);
    }
    });
    }
    0
  • QUOTE (Gades @ Nov 8 2010, 08:39 AM) <{POST_SNAPBACK}>
    Nice to know since the example on the FAQ is wrong then, i lost hours trying to figure it out since it seems to be one of the requirement of the Acceptance Criteria
    CODE
    function callAPI(url, callback) {
    if (KONtx.application.isPhysicalNetworkDown()) {
    log("the network is down!");
    return;
    }
    var request = new URL();
    request.callback = callback;
    request.location = url;
    KONtx.utility.WaitIndicator.up();
    request.fetchAsync(function (u) {
    KONtx.utility.WaitIndicator.down();
    if (u.response == 200){
    myWidget.application.setNetworkRequestFailed(false);
    u.callback(u.result);
    } else {
    myWidget.application.setNetworkRequestFailed(true);
    }
    });
    }

    The FAQ and this blog post clearly state that the newer KONtx.application.isPhysicalNetworkDown method may not be supported by older frameworks, and thus it's necessary to define it yourself for backwards-compatibility. This is taken verbatim from the FAQ:

    CODE
    2. Use a wrapper to test for the method's existence. Define this wrapper in init.js or someplace parsed once at runtime.

    if (typeof KONtx.application.isPhysicalNetworkDown === "undefined") {
    KONtx.application.isPhysicalNetworkDown = function () {
    // Replace myWidget with your widget's custom object
    return myWidget.network.isPhysicalNetworkDown();
    };
    }


    We realize that handling network disconnection is unnecessarily complex. The isPhysicalNetworkDown method addresses this and simplifies it, but unfortunately to handle older frameworks it will still be necessary to do some extra legwork which the blog post and the FAQ addresses. Arguably, it may still be confusing, and your feedback will help us clarify any documentation.

    Thanks,
    Ben
    0
  • You know the more I think about it, that blog post needs to be simplified even more. I recently wrote some code for a widget that handles cases for frameworks that support isPhysicalNetworkDown and also for older frameworks that don't with no changes needed to be made in any API call in the widget. I'll do another code review for sanity and then I'll post it shortly.

    Sorry for the confusion.

    - Ben
    0
  • Ok, I put this at the bottom of my init.js after the framework has been loaded:

    CODE
    if (typeof KONtx.application.isPhysicalNetworkDown === "undefined") {
    (function () {
    //first reassign the original function before deleting it; it's funky b/c it's a setter;
    var original = KONtx.application.setNetworkRequestFailed,
    setDownByUser = false;

    delete KONtx.application.setNetworkRequestFailed;

    KONtx.application.setNetworkRequestFailed = function (status) {
    original(status);
    setDownByUser = status;
    };

    KONtx.application.isPhysicalNetworkDown = function () {
    if (KONtx.application.getNetworkDownStatus) {
    return !setDownByUser;
    }
    return false;
    };
    }());
    }

    So, if it detects that KONtx.application.isPhysicalNetworkDown is undefined, it will define that and redefine KONtx.application.setNetworkRequestFailed, storing the original setter definition in the closure created by the self-executing function.

    Then, in my API call (there's only one in my widget), it's business as usual:

    CODE
                    if (KONtx.application.isPhysicalNetworkDown()) {
    log("Network is down, don't allow any xhr requests!");
    return;
    }

    var xhr = new XMLHttpRequest();
    xhr.open("GET", o.url, true);
    xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
    if (xhr.status === 200) {
    o.success(xhr);
    KONtx.application.setNetworkRequestFailed(false);
    } else {
    log("The xhr request failed.");
    o.error();
    KONtx.application.setNetworkRequestFailed(true);
    }
    }
    };
    xhr.send(null);

    The important thing here is that I still call KONtx.application.setNetworkRequestFailed to set the status of the network request, and I don't have to worry about creating a custom object and referencing that like has been noted in the docs. In other words, once I include that code in init.js, I don't need to be concerned anymore with whether the framework supports isPhysicalNetworkDown, as I've defined it in the case that it doesn't.

    Also, I find it really useful to use a proxy server when testing this in the wdk. We use polipo, and here are some steps to install it and use it:

    CODE
    #install polipo proxy
    sudo apt-get install polipo

    #lanch konfabulator with a proxy
    KF_PROXY=http://localhost:8123 Konfabulator

    #in another shell
    #bring down proxy
    sudo /etc/init.d/polipo stop

    #the uplink is now down, test away

    #bring the uplink back up
    sudo /etc/init.d/polipo start

    #rinse and repeat

    Lastly, this patch should be included as long as there are frameworks in the field that don't natively support isPhysicalNetworkDown. Also, I'm going to see to it that our docs (FAQ and blog post) are updated as soon as I can.

    - Ben
    0
  • Thanks for the tip, i'm trying it and it seems to work, i just have a problem now, after i shutdown polipo and the widget disconnects cause the network is down i can't seem to recover from it, everytime i try to relaunch it i have the dialog that says the network is down, i've catched the events i thought was the one i needed to catch but they are not doing anything ( and as i see in the terminal they are never fired )
    CODE
    	onNetworkFailed: function(event) {

    print('Network -> Failed ');
    KONtx.application.setNetworkRequestFailed(true);

    },



    onNetworkRestored: function() {

    print('Network -> Restored ');
    KONtx.application.setNetworkRequestFailed(false);

    },
    onNetworkConnectionReconnect: function() { //tried to subscribe also on this one just to see if i was able to make it work

    print('Network -> Restored ');
    KONtx.application.setNetworkRequestFailed(false);

    }


    And that's how i do the network request
    CODE
    var Network = {
    send: function(url,func,info) {
    if (KONtx.application.isPhysicalNetworkDown()) {
    log("the network is down!");
    return;
    }
    var request = new URL();
    request.location = url;
    request.func = func;
    request.info = info;
    request.fetchAsync(Network.finish);
    },

    finish: function(request) {
    if ( request.response == 200 )
    {
    KONtx.application.setNetworkRequestFailed(false);
    request.func(request.result,request.info);
    }
    else
    {
    KONtx.application.setNetworkRequestFailed(true);
    request.func(false,request.info);
    }
    }

    };
    0
  • Actually on the tv it works without problems, it's only in the simulator that it seems to not work for me
    0
  • I've tried but i still cannot the dialog "Connection Unavailable, The widget is unable to refresh its data and will be closed. Please try again later" go away, after i go to the dock with this dialog everytime i try to launch the widget it pops up and will not let me proceed, Any suggestion on how to proceed? I've also tried to subscribe to the onNetworkHideDialog but to no avail
    CODE
    	onNetworkHideDialog: function( event ) {
    KONtx.application.setNetworkRequestFailed(false);
    if(event.payload.type == 1) {
    event.preventDefault();
    }
    },
    0
  • QUOTE (Gades @ Nov 9 2010, 07:30 AM) <{POST_SNAPBACK}>
    I've tried but i still cannot the dialog "Connection Unavailable, The widget is unable to refresh its data and will be closed. Please try again later" go away, after i go to the dock with this dialog everytime i try to launch the widget it pops up and will not let me proceed, Any suggestion on how to proceed? I've also tried to subscribe to the onNetworkHideDialog but to no avail
    CODE
    	onNetworkHideDialog: function( event ) {
    KONtx.application.setNetworkRequestFailed(false);
    if(event.payload.type == 1) {
    event.preventDefault();
    }
    },

    Well, the onNetworkHideDialog event is only included starting in frameworks 1.3.21. Also, there is no onNetworkFailed event; maybe you're thinking of onNetworkDown? Either way, I would simplify by removing those listeners and just use the code that I had posted. If you're still experiencing the same issue, then I would start by logging the values in that patch I posted.

    Is the problem happening in the wdk, on the tv, or both?

    If it's happening on the tv, you can send logs to a remote server; see this post.

    Another thing, if you're caching data from the server, you could get in a situation where the widget checks to see if it has cached data before issuing an http request. If there's data in the cache, no request is sent. However, if a failed request happens after data has been cached, you could see get into a situation that when you open the widget, it sees it has data in the cache so it retrieves it there and doesn't send out a request; however, since the last failed request set the network down, the dialog that you describe will always be displayed since a new request can't be issued that would stop that from happening.

    This may not be your exact scenario, but you can appreciate how application logic could contribute to this problem.

    Hope that helps.

    - Ben
    0
  • The problem is happening on both the tv and the simulator, i think the issue is that i request data only in a child view and not in the sidebar view that is loaded when i select the snippet, in that view i only present a menĂ¹ where the users selects the category that it wants to be loaded, thus i'm not making network requests on the sidebar and so i don't have a chance to reset KONtx.application.setNetworkRequestFailed(); to true, so, when the widget loads after a disconnection, it always thinks the network is still down, for now i've tried to with setting setNetworkRequestFailed(); to false when activating the snippet, and that is pretty kinky i know, and i was thinking of doing a dummy network request when i load the sidebar from the snippet just to check if the network is still up or down. I've tried removing the listeners and just using the patch you provided but the problem is persisting.
    0
  • Tried to use
    CODE
    initialize: function() {
    this.parent();
    this._handleActivateSnippet.subscribeTo(this, ['onActivateSnippet'], this);
    },

    _handleActivateSnippet: function(event) {
    if (KONtx.application.isPhysicalNetworkDown()) {
    log("PHYSICAL NETWORK STILL DOWN");
    return;
    }else{
    log("NETWORK UP");
    KONtx.application.setNetworkRequestFailed(false);
    }
    log("activate snippet!");
    if(this.config.data && this.config.data.destinationId) {
    event.preventDefault();
    event.stopPropagation();
    KONtx.application.setHostResultToViewId(event, this.config.data.destinationId);
    }
    },

    but it's not working, everytime is goes through the if KONtx.application.isPhysicalNetworkDown() always returns false, even if i have shutdown polipo and the network is not available ( tried logging the the value inside the function, it sends the correct value when i'm using it before a network request ( true if the network is down or false if i have the network and i can proceed with the request) but it always returns false when i'm using it here to check the network before activating the view.
    0
  • Is any of the data in the second view (the one activated from your main sidebar) able to be fetched when the widget is loaded into memory or from the updateView listener in the main sidebar view? If so, I would fetch it in either of those two scenarios.

    I fetch some data in the onApplicationStartup listener.

    In init.js:
    CODE
    EventHandlers.onApplicationStartup.subscribeTo(KONtx.application, "onApplicationStartup", EventHandlers);


    Then, in Javascript/core/EventHandlers.js:
    CODE
    var EventHandlers = (function () {
    return {
    onApplicationStartup: function () {
    API.homeSpotlight(); //needs to be called when the widget is loaded into memory so the snip
    pet image can be fetched;
    },
    //snipped...
    };
    }());


    If you can't know to fetch any of the data until it's selected from the main sidebar, you could try a dummy fetch like you said just to see if the network is up and clear the dialog box if it is. Or, if you feel that the widget should be able to be interacted with regardless of network connectivity, you could call KONtx.application.setNetworkRequestFailed first thing in your xhr api. But, I highly recommend keeping your fetching code in only one place and have all your requests go through it. You don't want to have it scattered around your widget. You definitely want to know there's only one place where you're setting down the network.

    I have my xhr request api in Javascript/core/API.js.

    Remove as many moving parts as you can.
    0
  • I can't prefetch any data before selecting a category from the sidebar since i don't know what file to load.
    I've already have the fetch request in a separate file with a function that i call passing the appropriate url and callback function that i want called if the fetch is succesfull.
    The thing that bugs me is that the isPhysicalNetworkDown() function always returns false inside the snippet, even if the network is down, while it works without problems inside the widget, is it a bug checking the network inside the snippet?
    For now i think i'll try with the dummy fetch if i can't make the isPhysicalNetworkDown() to work inside a snippet.
    0
  • The dummy fetch seems to work, just with a little problem that bugs me a lot. Basically i call the dummy network request on the handleactivate snippet function that subscribes to the onactivatesnippet event. This causes a problem, that even if the network is up i need to start the snippet one time and get the error message that data can't be loaded before resetting the network stats to up.
    CODE
    var ToolboxSnippetView = new KONtx.Class({
    ClassName: 'ToolboxSnippetView',

    Extends: KONtx.system.AnchorSnippetView,

    initialize: function() {
    this.parent();
    this._handleActivateSnippet.subscribeTo(this, ['onActivateSnippet'], this);
    },

    _handleActivateSnippet: function(event) {
    log("NETWORK DOWN STATUS" + KONtx.application.getNetworkDownStatus);
    Network.send('Dummy-URL',this.activation,{view:this, mess:'Feed Loaded '});
    if(this.config.data && this.config.data.destinationId) {
    event.preventDefault();
    event.stopPropagation();
    KONtx.application.setHostResultToViewId(event, this.config.data.destinationId);
    }
    log("activate snippet!");
    },
    activation: function(response,extra){
    log("NETWORK DOWN STATUS DENTRO ACTIVATION" + KONtx.application.getNetworkDownStatus);

    },
    ......

    Is there another event i can subscribe that is fired when the widget is just shown on the dock and so i can do the network request there without needing to activate it once for resetting the network status?
    0
  • QUOTE (Gades @ Nov 11 2010, 12:56 AM) <{POST_SNAPBACK}>
    The dummy fetch seems to work, just with a little problem that bugs me a lot. Basically i call the dummy network request on the handleactivate snippet function that subscribes to the onactivatesnippet event. This causes a problem, that even if the network is up i need to start the snippet one time and get the error message that data can't be loaded before resetting the network stats to up.
    CODE
    var ToolboxSnippetView = new KONtx.Class({
    ClassName: 'ToolboxSnippetView',

    Extends: KONtx.system.AnchorSnippetView,

    initialize: function() {
    this.parent();
    this._handleActivateSnippet.subscribeTo(this, ['onActivateSnippet'], this);
    },

    _handleActivateSnippet: function(event) {
    log("NETWORK DOWN STATUS" + KONtx.application.getNetworkDownStatus);
    Network.send('Dummy-URL',this.activation,{view:this, mess:'Feed Loaded '});
    if(this.config.data && this.config.data.destinationId) {
    event.preventDefault();
    event.stopPropagation();
    KONtx.application.setHostResultToViewId(event, this.config.data.destinationId);
    }
    log("activate snippet!");
    },
    activation: function(response,extra){
    log("NETWORK DOWN STATUS DENTRO ACTIVATION" + KONtx.application.getNetworkDownStatus);

    },
    ......

    Is there another event i can subscribe that is fired when the widget is just shown on the dock and so i can do the network request there without needing to activate it once for resetting the network status?

    Yes, onApplicationStartup. See my above post.

    Don't check for network connectivity in a sidebar view, it's just not a good idea.

    - Ben
    0

Recent Posts

in General - Yahoo! TV Widgets