Background Synchronisation of Data using WebServic

Topics: Mobile Client Software Factory
Sep 26, 2006 at 7:07 AM
originally posted by: johnkattenhorn

Hi,

I've got a web service which i would like to poll in an interval (and eventually make driven by an event), which would check for valid network connection and then update the offinedatastore with new data.

All of the components are there i think such as connection broker, disconnected service agent etc ? Has anyone done anything like this or have a suggested approach ?

Should this process be kicked off using the rootworkitemcontroller etc ?

Thanks

John
Sep 26, 2006 at 7:58 AM
originally posted by: m_a_madero

We did a ThreadDispatcher Service. So that we just send the Request and we forget about it and after an X configurable minutes it sends all the requests using the DSA block.

We would have liked to extend the RequestManager, so that we would only deal with an interface, then we would configure the RequestManager and Endpoints to set the timer for each one.

Something similar would work for you, only that instead of sending the Request and the let the Thread Dispatcher take care of sending it, just Start a ThreadDistpatcher service that will constantly send the same Request.

The tricky part here, is that as you update the OfflineDataStore, you would have to be careful that nothing is locked.

Hope this helps.
Sep 26, 2006 at 12:02 PM
originally posted by: johnkattenhorn

Hi,

Thanks for the advice, Is the TreadDispatch Server part of the MCSF or addtional ?

Your right about the locking in the offline store, i've though about this quiet a lot. I could'nt decide what the best approach was going to be; Briefly my sincero is :

1) I have a Web Service (built using the Service Factory) which extracts information out of a 'closed' oracle based application.
2) I store this information in the offline datastore.
3) User updates some / all of the information from the offline datastore.
4) Transmit the information back to the 'closed' oracle based application using another web service.

Since i cannot modify the closed application we use business procedures to try to stop data conflict, i.e. When data assigned to mobile user any updates performed in the closed application maybe overwritten by data on handheld.

I still not completely happy on how i identify which records have been updated by the mobile client and the inteaction with the polled webservice which will try to refresh the data on the handheld as it has no idea which data actually made it back to the handheld.

Interesting problem made worst by not being able to modify the backend system !!

Any thoughts ?

Thanks

John
Sep 26, 2006 at 1:25 PM
originally posted by: m_a_madero

So this is what we do.
We have a modele and it the ModuleInitializer:

private void Initialize()
{
TimerDispatcher threadDispatcher = workItem.RootWorkItem.Items.AddNew<TimerDispatcher>();
threadDispatcher.Start();
}

The ThreadDispatcher is a really simple class with a timer:
public class TimerDispatcher
{
private const int MILLISECONDS = 60000;
private static System.Threading.Timer threadTimer;
EventPublication("topic://RequestStatusChanged",PublicationScope.Global)
public event EventHandler RequestStatusChanged;
public void Start()
{
TimerDispatcherState lockObject = new TimerDispatcherState();
threadTimer = new System.Threading.Timer(RevisarPedidos, lockObject, MILLISECONDS, MILLISECONDS);
lockObject.Timer = threadTimer;
}

public void RevisarPedidos(object state)
{
TimerDispatcherState dispatcherState = (TimerDispatcherState)state;
dispatcherState.Timer.Change(Timeout.Infinite, Timeout.Infinite);
lock (dispatcherState.lockObject)
{
bool hasChanged = false;
IRequestQueue queue = RequestManager.Instance.RequestQueue;
IEnumerable<Request> requests = queue.GetRequests(2);
foreach (Request request in requests)
{
// Si tenemos dos estampas y ha pasado el tiempo de revision, entonces le movemos al numero de estampas.
if (request.Behavior.Stamps==2 && request.Behavior.QueuedDate.HasValue && DateTime.Now.Subtract(request.Behavior.QueuedDate.Value) >= new TimeSpan(0, ConfigurationHelper.MinutosParaEnviarVenta, 0))
{
hasChanged = true;
queue.Remove(request);
request.Behavior.Stamps = 9;// TODO: Obtener el número de estampas que corresponden a ese request.Endpoint;
queue.Enqueue(request);
}
}

if (hasChanged && RequestStatusChanged != null)
RequestStatusChanged(this, EventArgs.Empty);
}
dispatcherState.Timer.Change(MILLISECONDS, MILLISECONDS);
}
}

We use the TimerDispatcherState to start/stop the timer and sync de locks.
public class TimerDispatcherState
{
public TimerDispatcherState()
{
lockObject = new object();
}
public object lockObject;
private Timer timer;

public Timer Timer
{
get { return timer; }
set { timer = value; }
}
}

We change the stamps of the Requests so that the RequestManager doesnt sent it.