Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / Windows Forms

SyncBox - An Online Storage Alternative

Rate me:
Please Sign up or sign in to vote.
4.90/5 (11 votes)
27 Dec 2009CPOL6 min read 34.2K   1K   41   4
An alternative way to get Online Storage on top of a version control system like Subversion
SyncBox_-_Screenshot.png

Table of Contents

Introduction

I think more and more people are using some kind of online file storage nowadays. This type of storage makes your private files accessible from any computer and most people are perfectly satisfied and comfortable with it. At least those lucky ones who are not limited by some fixed enterprise security policy restrictions that prevent them from using popular services like GDrive, SkyDrive, DropBox, Mozy, WebDAV, etc. If you happen to be one of them, being perfectly happy using these services, then the ideas in this article may not be interesting for you. However if that storage works fine only for your home computers and not your company computers (like my exact case), then please have a look at my proposal below.

Basically, this article presents an idea to solve this problem. We'll be using one of the free online version control servers out there for hosting the files. Simply add your files to your version control repository of your choice – e.g. this article uses Slik SVN since it's a free one – and you can access them from any computer. Thus, it can serve as an alternative “online storage”, you should have no problems using it even behind corporate firewalls (note that I do not declare myself as a network expert, thus I won't even try to describe why the “classic” online storage services don't work in some enterprises and why the version control service does; the SyncBox tool is merely based on observations of that different behavior).

Online_Storage_vs_SVN_Repository.png

When online storage services do not work across enterprise boundary, SVN does. Note that SyncBox doesn't need to deal directly with your files.

Now the drawback with using version control this way is that you'll want to update your local files each time there's a new version in the server repository and also check in your local files to the repository each time you modify them. This is where SyncBox will help you a lot: SyncBox is a tiny desktop utility running silently in the background and synchronizing your files automatically with the help of the SVN client installed on your machine.

Synchronization Core: ISyncWorker + ISyncClient

Actually, SyncBox doesn't synchronize the files directly. It does this indirectly, calling the SVN command line client when appropriate. That is, SyncBox automates the job of the SVN client in both directions: locally changed files are checked in automatically (after an adjustable time delay) and out-of-date files are updated from the remote server automatically. This way the whole synchronization process is transparent for the user and made silently on the background.

This whole update/check-in process uses an abstraction through the main interfaces ISyncWorker and ISyncClient. The “sync worker” is a non-blocking wrapper around the SVN command line client and the “sync client” is the main application logic issuing synchronization requests to the “sync worker”.

MC++
public interface class ISyncWorker
{
	// Calls to ISyncWorker interface should return immediately: 
         // with an asynchronous
	// result retrieved through appropriate '...Finished' event handler.
	void SetClient(ISyncClient^ pClientToCallback);
	bool Update();
	bool CheckIn();
	bool IsBusy();
	void RequestWorkerStop(bool finishAllJobsFirst);

	// Synchronous call (caller needs immediate and quick results - 
         // no Internet connection can be used)
	bool IsFileModifiedImmediately(String^ fileName);

	event UpdateStartedHandler^     UpdateStarted;
	event UpdateFinishedHandler^    UpdateFinished;
	event CheckInStartedHandler^    CheckInStarted;
	event CheckInFinishedHandler^   CheckInFinished;
	event WorkerStoppedHandler^     WorkerStopped;

	event ConnectionErrorHandler^	ConnectionErrorOccurred;
};

When the “sync worker” deals with the SVN command line client, possibly waiting for a response through the network, it will do so in a background thread – it won't block SyncBox's main GUI thread. That's why all the interface methods must return immediately – mostly they just issue some SVN requests. When the response for those asynchronous requests is available later, the appropriate interface event will be fired by the “sync worker”.

MC++
public interface class ISyncClient
{
	enum class LogActionDestination
	{
		LogToFile = 0x1,
		LogToOutputWindow = 0x2,
		LogToAllDestinations = 0xF
	};

	List<string^ />^ GetSourceControlledFolders();
	void LogAction(String^ msg);
	void LogAction(String^ msg, LogActionDestination logDestination);
};

The ISyncClient implementation will know which local folders contain files that need to be synchronized between local and remote versions (actually, only files contained in the SVN repository are included). Further, it also contains some event logging possibility to be used by the “sync workers”.

Dynamic Update Interval

First, the SyncBox tool must make sure all your files are always up-to-date. It does so by periodically checking and querying the SVN repository if there are some newer versions of your files available on the remote server. If there are, then it will retrieve the newest versions immediately. The length of these periodic intervals in minutes can be set directly by the user. However, this is not a fixed value. If you're not working on your computer currently, then it's OK to use longer update intervals, thus free up the network usage whenever possible. That's why SyncBox uses a Dynamic Update Interval which means when you lock your Windows session, then the update interval will be temporarily doubled after some time. While you are still away from your computer, this doubling will repeat several times until a maximum of 1 hour is reached. Then, as soon as you return to your computer and unlock your Windows session, all these interval changes will be reverted and the value set by you will take place immediately from that moment on.

SyncBox_-_Dynamic_Update_Interval.png

This dynamic timer behavior is achieved by a special Timer subclass called DynamicTimer:

MC++
// DynamicTimer is a timer which dynamically slows down.
// On each tick, its timer interval gets multiplied by the value 
// of 'IntervalMultiplyFactor'.
// However, timer interval will always be limited to 'MaxInterval'.
ref class DynamicTimer : public System::Windows::Forms::Timer
{
public:
	DynamicTimer(void);

	property int IntervalMultiplyFactor; 	// time period get multiplied 
						//by this number on each tick
	property int MaxInterval; // maximal time period between ticks, in minutes
	
	event System::EventHandler^ IntervalAutoChanged;
};

You use it as a normal Timer class, however it will also follow your instructions on “slowing down” the ticks according to the MaxInterval and IntervalMultiplyFactor properties. In the case of SyncBox, these properties are set when the Windows session is locked/unlocked, since SyncBox registers itself for these system notifications through the WTSRegisterSessionNotification() API:

C#
void SyncBoxCLR::MainForm::WndProc(Message% m)
{
	if (m.Msg == WM_WTSSESSION_CHANGE)
	{
		if (m.WParam.ToInt32() == WTS_SESSION_LOCK) // Computer Locked
		{
			LogAction(L"Computer Locked");
			this->timerUpdate->IntervalMultiplyFactor = 2;
		}
		else if (m.WParam.ToInt32() == WTS_SESSION_UNLOCK) // Computer Unlocked
		{
			LogAction(L"Computer Unlocked");
			this->timerUpdate->IntervalMultiplyFactor = 1;
			requestUpdate();
		}
	}
	...
	...
}

Delayed Check-In

When you change a local file, you'll want to have it uploaded to the remote SVN server – to make it accessible from any other computer of yours. Also, by checking it into the repository, you'll create a new revision (a new version of that file) in your SVN repository, which is fine. However if you are editing a text document, you probably don't wish to create and upload a new revision of that file each time you press Ctrl+S in your favorite word processor, do you? If not, SyncBox can delay your check-ins by the amount of time you like the best. You can set a non-zero interval of “Check-ins Delay” and whenever SyncBox will detect a local file change, it will create and start a time window for that request. If another file change will happen during that time frame, then the time window will be reset and the check-in will be delayed again. However, if no further editing is made by you during that time, then all your changed files will be uploaded to the SVN repository at once when the time window expires (e.g. if there were no file changes for 15 minutes – provided that you've set a 15 minutes value for the “Check-ins Delay”). This behavior is achieved through the RequestTimeWindow class with the following, very easy interface:  

C#
ref class RequestTimeWindow
{
public:
	RequestTimeWindow(void);

	property int Period; // timer check in minutes
	property bool IsActive
	{
		bool get();
	}
	event System::EventHandler^ NewRequestAdded; 	// time window started 
						//or restarted
	event System::EventHandler^ TimeWindowExpired;  // time window stopped

	void AddRequest();
	void CancelAllRequests();
};

Extensible Architecture

Since SyncBox's core code doesn't deal directly with the SVN repository, any other, alternative version control repository can be used by SyncBox internally. If you are interested, you can create your own ISyncWorker implementation and hook it up easily with SyncBox's ISyncClient internally.

SyncBox_Architecture_UML.png

SyncBox manages your files indirectly, through a 3rd-party source control client installed on your computer.

Future Enhancements

This tiny tool has been developed to be used by some of my colleagues and also by me personally, so it may seem that some functionality you would expect is still missing. If that's the case, please let me know, I'll be glad to hear what and where you think could be improved.

For example, there is some place for enhancement in handling of synchronization conflicts which must be made manually through the SVN client currently or adding/removing files to/from the repository which is a similar, non-automated task. Anyway, your feedback on any enhancements is highly appreciated.

History

  • 27 Dec 2009: Initial revision

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Slovakia Slovakia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
e1nice23-Sep-11 20:45
e1nice23-Sep-11 20:45 
Questiongreat article Pin
jerry_wangjh27-Jun-11 3:15
jerry_wangjh27-Jun-11 3:15 
Questionhow do i set the connection string with my own SVN account Pin
wleon24-May-10 7:12
wleon24-May-10 7:12 
AnswerRe: how do i set the connection string with my own SVN account Pin
Attila Kúr24-May-10 9:54
Attila Kúr24-May-10 9:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.