Windows Azure Platform Developer Center > Azure Forums > Live Framework > ChangeNotification events detects new object, but new object nowhere to be found?
Ask a questionAsk a question
 

AnswerChangeNotification events detects new object, but new object nowhere to be found?

  • Thursday, February 05, 2009 11:34 PMavs Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I have an application connected to cloud moe. I use the LiveFxResourceBrowser, and I add a mesh object to the local moe.

    The application receives the change notification. However, when I enumerate the mesh objects, the new object is not there. (Even tho it is there in the LiveFxResourceBrowser on both local and cloud moe). Even when I typecasted the sender in the callback, to a liveitemcollection, and enumerated that, the new object still wasn't there... I set a timed callback, to re-enumerate every couple seconds... Still the new object is not there...

    However, if I toss the session, and re-login to the cloud moe, the object now appears when I enumerate the mesh objects.

Answers

  • Friday, February 06, 2009 12:08 AMRajan DwivediMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I guess that you are using .Net rich client SDK. They generally cache the list of objects when you use it the first time. The SDK library loads collection into the memory if you are using kind "from meshObject in mesh.MeshObjects.Entries" of syntax. You can verify this using Fiddler, such code generates no network traffic. It loads the data from the local in-process copy of the data. Any subsequent requests will continue to be processed by the local data.

    I believe if you try CreateQuery<T> then it will make a GET request (LINQ-URI translation happens) to the server (cloud LOE) for query processing. if the list is huge, you may need to use pseudo functions like $take and $skip for pagination. The CreateQuery() method provides a way for the developer to proxy portions of the LINQ query to the server. The tookit classes will break the query down and construct a GET request with appropriate url parameters in order to do much of the work on the server in order to optimize the network traffic.

    A recommendation would be to either always use Entities or always use CreateQuery() except when perf is super important. For example, if the data set is substantially large then CreateQuery with filtering would make the most sense. If speed of access is key and freshness of the data is less so, then the Entities query could be used.

    BTW, when you receive change notification, you can access mo right there, example:

    void mo_ChangeNotificationReceived(object sender, EventArgs e)

    {

    MeshObject mo = (MeshObject)sender;

    SetStatusText(mo.Resource.Title + " change notification");

    }

    Or let us say if the change notification is for datafeeds:

    void DataFeeds_ChangeNotificationReceived(object sender, EventArgs e)

    {

    LiveItemCollection<DataFeed, DataFeedResource> LI = (LiveItemCollection<DataFeed,DataFeedResource>)sender;

    MeshObject mo = GetMeshObjectParent(LI.SelfLink);

    foreach (DataFeed df in LI.Entries)

    {

    SetStatusText(df.Resource.Title + " change notification in " + mo.Resource.Title);

    }

    }


    Here is the utility function for getting parent Mo:

    private MeshObject GetMeshObjectParent(Uri selflink)

    {

    foreach (MeshObject mo in mesh.MeshObjects.Entries)

    {

    if (selflink.ToString().Contains(mo.Resource.SelfLink.ToString()))

    {

    return mo;

    }

    }

    return null;

    }


    Last but not least, ChangeNotifications don't work as expected for Silverlight Apps (S/MEWA) either for local LOE or cloud. For rich apps, there are some anomalies between cloud LOE and the local LOE in regards to change notifications. We will fix this in the future release.

    Hope this helps,

    Rajan









    (This post is provided "AS IS" with no warranties, and confers no rights.)
  • Friday, February 06, 2009 5:22 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Are you writing something like this?

    meshCloud.MeshObjects.ChangeNotificationReceived += new EventHandler(MeshObjects_ChangeNotificationReceived);

    So the problem is: If you add a MeshObject to the cloud MOE, once the notification callback is invoked, you'll be able to find the new object in the LiveItemCollection got from the sender parameter. However, if you add a MeshObject to the local MOE, when the notification callback is invoked, you won't be able to find the new object.

    Yes, I've verified it on my side. This can potentially be a bug... Can you submit a feedback on our Connect site? https://connect.microsoft.com/liveframework/Feedback. Thanks.

    As a workaround, you can create a query (meshCloud.CreateQuery<MeshObject>) in the callback. The new MeshObject has already been synched to the cloud, just it doesn't appear in the sender parameter...
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Friday, February 06, 2009 10:33 AMRajan DwivediMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    AVS,

    Thank you for sharing some more details. There are issues between the local LOE and cloud LOE regarding change notifications. I would recommend to use the cloud endpoint only - it seems to work. You can leave sync up responsibility to local runtime with the cloud. Assuming that these issues will be fixed in the near furture, you can test your app by just changing the end-point. ITo sumarize, your problems are related to the following issues:

    1) Discrepancies between Local LOE vs. Cloud LOE (this was due to PDC'2008 based realse constraint)
    2) Latency in Syncup
    3) Query Model/Caching (.NET SDK)


    If you are working with the newsitems, I have tested that this works if I am using against the cloud LOE. Example, I subscribe to MO and then post a comment as news locally. It reaches Live Desktop and change notification is fired. It also works vice versa, if I add a comment on Live Desktop, it reaches my app through receive notification handler. As I am using it on existing MO - so I can retrieve it easily. For new MO, you may have to change the GetParent method that I posted earlier in above response.

    Here's some code snippet that can help you like you mentioned related to Datafeed:

    void DataFeeds_ChangeNotificationReceived(object sender, EventArgs e)
            {
                LiveItemCollection<DataFeed, DataFeedResource> LI = (LiveItemCollection<DataFeed,DataFeedResource>)sender;
                MeshObject mo = GetMeshObjectParent(LI.SelfLink);
                foreach (DataFeed df in LI.Entries)
                {
                    SetStatusText(df.Resource.Title + " change notification in " + mo.Resource.Title);
                }
            }



    Many thanks,

    Rajan
    (This post is provided "AS IS" with no warranties, and confers no rights.)

All Replies

  • Friday, February 06, 2009 12:08 AMRajan DwivediMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I guess that you are using .Net rich client SDK. They generally cache the list of objects when you use it the first time. The SDK library loads collection into the memory if you are using kind "from meshObject in mesh.MeshObjects.Entries" of syntax. You can verify this using Fiddler, such code generates no network traffic. It loads the data from the local in-process copy of the data. Any subsequent requests will continue to be processed by the local data.

    I believe if you try CreateQuery<T> then it will make a GET request (LINQ-URI translation happens) to the server (cloud LOE) for query processing. if the list is huge, you may need to use pseudo functions like $take and $skip for pagination. The CreateQuery() method provides a way for the developer to proxy portions of the LINQ query to the server. The tookit classes will break the query down and construct a GET request with appropriate url parameters in order to do much of the work on the server in order to optimize the network traffic.

    A recommendation would be to either always use Entities or always use CreateQuery() except when perf is super important. For example, if the data set is substantially large then CreateQuery with filtering would make the most sense. If speed of access is key and freshness of the data is less so, then the Entities query could be used.

    BTW, when you receive change notification, you can access mo right there, example:

    void mo_ChangeNotificationReceived(object sender, EventArgs e)

    {

    MeshObject mo = (MeshObject)sender;

    SetStatusText(mo.Resource.Title + " change notification");

    }

    Or let us say if the change notification is for datafeeds:

    void DataFeeds_ChangeNotificationReceived(object sender, EventArgs e)

    {

    LiveItemCollection<DataFeed, DataFeedResource> LI = (LiveItemCollection<DataFeed,DataFeedResource>)sender;

    MeshObject mo = GetMeshObjectParent(LI.SelfLink);

    foreach (DataFeed df in LI.Entries)

    {

    SetStatusText(df.Resource.Title + " change notification in " + mo.Resource.Title);

    }

    }


    Here is the utility function for getting parent Mo:

    private MeshObject GetMeshObjectParent(Uri selflink)

    {

    foreach (MeshObject mo in mesh.MeshObjects.Entries)

    {

    if (selflink.ToString().Contains(mo.Resource.SelfLink.ToString()))

    {

    return mo;

    }

    }

    return null;

    }


    Last but not least, ChangeNotifications don't work as expected for Silverlight Apps (S/MEWA) either for local LOE or cloud. For rich apps, there are some anomalies between cloud LOE and the local LOE in regards to change notifications. We will fix this in the future release.

    Hope this helps,

    Rajan









    (This post is provided "AS IS" with no warranties, and confers no rights.)
  • Friday, February 06, 2009 12:15 AMRajan DwivediMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    BTW, I just noticed that the parent Mo can be retrieved if it already exists in the collection (cache) but the new MO that you created will require dynamic GET query.
    (This post is provided "AS IS" with no warranties, and confers no rights.)
  • Friday, February 06, 2009 2:34 AMavs Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I received the change notification, but the object received was a LiveItemCollection of MeshObjects. When I enumerated those objects, the new object was not in it.
  • Friday, February 06, 2009 5:22 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Are you writing something like this?

    meshCloud.MeshObjects.ChangeNotificationReceived += new EventHandler(MeshObjects_ChangeNotificationReceived);

    So the problem is: If you add a MeshObject to the cloud MOE, once the notification callback is invoked, you'll be able to find the new object in the LiveItemCollection got from the sender parameter. However, if you add a MeshObject to the local MOE, when the notification callback is invoked, you won't be able to find the new object.

    Yes, I've verified it on my side. This can potentially be a bug... Can you submit a feedback on our Connect site? https://connect.microsoft.com/liveframework/Feedback. Thanks.

    As a workaround, you can create a query (meshCloud.CreateQuery<MeshObject>) in the callback. The new MeshObject has already been synched to the cloud, just it doesn't appear in the sender parameter...
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Friday, February 06, 2009 5:44 AMavs Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    That sounds sort of like what I'm doing. I'm setting the event handler exactly as you described. I am also adding a mesh object to the local moe in the event handler, however I'm enumerating the collection first and only add a new object if I find a particular object in the collection. (The object that was added on the cloud moe). So if the object isn't found, I don't add anything on the client moe.

    I'm playing around with a couple different ways to accomlpish the same thing. At the moment, I'm rewriting it to use feeds instead, since it seems like the feed notifications seem to work more reliably.

    I tried using NewsItems previously, but I could never get the news items I added on the local moe to show up on the cloud moe. Is there something I need to call to get the news items to propagate to the cloud moe? I'm currently only creating the newsitem and adding it to the meshobject. If I look at LiveFxResourceBrowser, I see the news item/entry on the local moe, but the cloud moe's news is empty.

    Thanks for all the help :)

    bryan
  • Friday, February 06, 2009 10:33 AMRajan DwivediMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    AVS,

    Thank you for sharing some more details. There are issues between the local LOE and cloud LOE regarding change notifications. I would recommend to use the cloud endpoint only - it seems to work. You can leave sync up responsibility to local runtime with the cloud. Assuming that these issues will be fixed in the near furture, you can test your app by just changing the end-point. ITo sumarize, your problems are related to the following issues:

    1) Discrepancies between Local LOE vs. Cloud LOE (this was due to PDC'2008 based realse constraint)
    2) Latency in Syncup
    3) Query Model/Caching (.NET SDK)


    If you are working with the newsitems, I have tested that this works if I am using against the cloud LOE. Example, I subscribe to MO and then post a comment as news locally. It reaches Live Desktop and change notification is fired. It also works vice versa, if I add a comment on Live Desktop, it reaches my app through receive notification handler. As I am using it on existing MO - so I can retrieve it easily. For new MO, you may have to change the GetParent method that I posted earlier in above response.

    Here's some code snippet that can help you like you mentioned related to Datafeed:

    void DataFeeds_ChangeNotificationReceived(object sender, EventArgs e)
            {
                LiveItemCollection<DataFeed, DataFeedResource> LI = (LiveItemCollection<DataFeed,DataFeedResource>)sender;
                MeshObject mo = GetMeshObjectParent(LI.SelfLink);
                foreach (DataFeed df in LI.Entries)
                {
                    SetStatusText(df.Resource.Title + " change notification in " + mo.Resource.Title);
                }
            }



    Many thanks,

    Rajan
    (This post is provided "AS IS" with no warranties, and confers no rights.)
  • Friday, February 06, 2009 7:03 PMavs Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I rewrote my application to use feeds, and it sems to work :) It takes about 20-30 seconds for all the data to get propagated back and forth, but that is to be expected... The Local MOE did seem a bit unstable tho. Every once in a while, the call to "Update" would throw an exception saying the remote server (Local MOE) returned "Unauthorized". I couldn't figure out why it suddenly broke... However, if I shut down the local LiveFx client, and relaunched it, everything started working again.
  • Monday, March 16, 2009 7:45 PMkzuMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I'm interested in a response to the other question, which is how to add a NewsItem to the *local* LOE and have it automatically pushed to the cloud LOE (and from there to the other devices/users).

    I see discrepancies here between what the Live Mesh Beta (from mesh.com) does and what my experimentation with the Live Framework APIs (dev CTP) do:

    1 - Live Mesh Beta mesh folders feature allows you to post a New Post entry which looks like a chat thingy. If you're offline, the entry doesn't show up in the news stream until you're actually back online, at which point it's also propagated to the cloud and the rest of the devices/users.
    2 - If I add a new NewsItem to the News associated with a MeshObject via the Live Framework API, I get different behavior:
       a) If I'm online (connected to cloud LOE), seems to work just fine and very much like the live mesh beta client.
       b) If I'm offline (connected to local LOE), entries that I post are only added locally, and are NEVER pushed to the cloud, even when I come back online.


    I'm looking at a way of building an ad-hoc chat channel over Live Mesh...

    Thanks in advance!

    Working with GAX/GAT/DSL? Download SFT now! http://softwarefactoriestoolkit.net