locked
What’s the best way to force Client to do full refresh ? RRS feed

  • Question

  • Used:

    Sync Framework v. 2.1 and SqlSyncProvider’s

    Synchronizing SQL 2008 R2 (server) with SQL Express 2008 (client).

     

    Scenario I’m trying to implement:

    Server and Client are provisioned. Client downloads all the data from Server. Synchronization works fine.

    Let’s say after some period of time I would like to import new data into Server (from some external source) and then to be sure that each Client performs full refresh next time before trying to synchronize with Server. Under “full refresh” I mean deletion of everything what Client has and downloading all the data from the Server.

     

    Question. Is there any way to detect this somehow and ensure that Client downloads all data from Server ? What’s the best way to achieve  this ?

     

    At the moment I have an idea, but it requires some manual steps to be implemented storing information which Client already has downloaded all data:

    0.       This means, that I need to store somewhere (let’s say in ‘SyncStatus’ table) information that particular Client downloaded all data from Server during initial synchronization.

    1.       For importing data into Server from external source, I’m thinking to implement these steps: deprovision Server, import data from the external source, provision Server, clear out ‘SyncStatus’ table.

    2.       Before Client starts synchronization – add a check for the appropriate record in ‘SyncStatus’ table:

    2.1. If an entry for that Client exists – perform synchronization as usual;

    2.2. If no entry – deprovision/reprovision Client and download all the data from the Server. After successful download update ‘SyncStatus’.

     

    Thanks.

     

    Monday, October 24, 2011 8:22 PM

All replies

  • will the Import on the server bring in a totally different set of data than what it contains and previously synched with clients?

    if you're just adding new data, i'll skip the deprovisioning stuff on the server (not unless you're redefining the scope configuration). and just let the client sync the incremental changes for the newly imported data.

    to force a full refresh on the client, you have to delete the previously downloaded data as well in addition to deprovisioning/reprovisioning. Otherwise, the sync may fire conflicts on your first sync.

     

     

    Tuesday, October 25, 2011 1:36 AM
  • Import from external source brings completely different dataset. Well, basically there may exist the same entities from the business world point of view but Primary keys in the external database for these entities may differ from the already existing ones in Server. Import from external source works in the way deleting all data and then inserting everything. I don’t see a problem at this point to deprovision/clear out/import/provision Server.

     

    My biggest concern is in a detection whether Client needs a full refresh. Is there anything built-in in Sync Framework that might be useful in my scenario automatically detecting a need for full refresh (having in mind that Server has been deprovisioned/provisioned and has no knowledge about the client)? Or it would be simpler to implement my custom logic to handle this using some download status table like it is described in my first post ? 

      

    Knowing that full refresh is needed it’s not a big deal to deprovision/clear out/provision and synchronize the Client.

     

    Thanks.

    Tuesday, October 25, 2011 9:14 AM
  • nothing in the api that would allow you to explicitly determined if a full refresh is required.

    the only problem that i see in custom status table is that you have to make sure its always up to date. so for example, the flag may have been set as client requiring refresh, you do the refresh and an error occured when you try to set the status flag that the client has refreshed already.

    i havent tested this, but another approach you can try is cleaning up the metadata in the server. when the metadata is cleaned up, the client will get a SyncPeerOutdate event that you can intercept. you can then reinitialize the client.

    check out How to: Clean Up Metadata for Collaborative Synchronization (SQL Server) in the docs.

    Tuesday, October 25, 2011 10:58 AM
  • JuneT, thanks for your responses.

     

     

    I’ve tried Server Metadata Cleanup and I have doubts I can trust this approach since Client is able upload its data without exceptions in some cases. The steps I’ve performed:

     

    I deleted all the records from Server and cleaned up metadata setting RetentionInDays to 0. Then I inserted several rows in Server table and tried to synchronize:

     

    1.       Download of data from Server to Client raised a SyncPeerOutdated event what is expected to happen. It’s fine.

    2.       But upload of data from Client to Server didn't raise a SyncPeerOutdated event. BTW, there is raised an ApplyChangeEvent event (Conflict Type is LocalCleanedupDeleteRemoteUpdate) at Server database but only for the rows modified in Client (what is expected to happen). If a row in Client is added – Client uploads everything successful and in my scenario this is not acceptable.


    • Edited by kambarda Tuesday, October 25, 2011 1:17 PM
    Tuesday, October 25, 2011 1:13 PM
  • It seems I’ve found a workaround how to check a need for the full refresh before Client uploads to Server without using additional tables to track download state.

     

    The idea is before starting synchronization on uploading Clients data to Server always try to run an additional download from Server to Client which lets to decide if a full refresh is needed. The additional download I’m executing with batching enabled and batch size set to small enough:

    1)      if Servers metadata are cleaned up and Client needs a full refresh – a  SyncPeerOurdated event is raised which lets the application to prevent from any Client uploads.

    2)      if Servers metadata are not cleaned up – in theory Client should receive Servers changes, but at the very first BatchSpooled event I’m throwing my custom exception which interrupts this download session and lets the application to know that Client does not need a full refresh and can upload its data to the Server.

     

    Is this solution good enough ? Is there anything else I should take into account ?

    Tuesday, October 25, 2011 6:31 PM
  • how about simply changing the sync direction to DownloadAndUpload? that way the SyncPeerOutdated get's fired first ?
    Wednesday, October 26, 2011 1:10 AM
  • Well, this  would be useful if all Clients in the community always downloaded and then uploaded their changes.

     

    But there are at least two use cases when Client should know whether he needs a full refresh:

    1.       When Client wants only to upload his changes (i.e. some minor change at that moment and the rest at the end of the day);

    2.       On application load it would be worth to notify the user that his data needs to be refreshed.

     

    Anyways, thanks for the ideas and of course for the confirmation that there is nothing built-in in the api allowing automatically detect if a full refresh is required.

     

     

    Wednesday, October 26, 2011 2:45 PM