Tuesday, October 20, 2015

Hosting Evernote .Net SDK in Godaddy or other hosting provider

There is no doubt that Evernote is a simple but great product. It was simple desktop application in the begining and moved to cloud at the right time. Cloud storage helps our notes to be synced across technology, platform and devices.

I was a proud user of Google notes. But Google shut it down. From that moment, I moved to Evernote cloud.

Evernote SDK for .Net - Using local file system

Evernote has exposed APIs to interact with out notes and there is SDK for programming models which help us to use the API easily. But if we try to host our application which the Evernote SDK in Godaddy just to read the notes, we will  get errors as Godaddy is not providing file system access. It will happen in all the shared hosting providers where our code don't have access to full file system. First it will ask to give full trust. After giving full trust we will get more specific exception. Details below


Exception:System.UnauthorizedAccessException Message:Access to the path '\Evernote\EvernoteSDK' is denied. Exception:System.UnauthorizedAccessException 

Message:Access to the path '\Evernote\EvernoteSDK' is denied. 

StackTrace: 
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost) 
at System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost) 
at System.IO.Directory.CreateDirectory(String path) 
at EvernoteSDK.Advanced.ENPreferencesStore.Save() 
at EvernoteSDK.Advanced.ENPreferencesStore.SetObject(Object objectToStore, String key) 
at EvernoteSDK.ENSession.PerformPostAuthentication() at EvernoteSDK.ENSession.Startup()
at EvernoteSDK.ENSession..ctor() 
at EvernoteSDK.ENSession.<.cctor>b__10() 
at System.Lazy`1.CreateValue() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
at System.Lazy`1.get_Value() 
at EvernoteSDK.ENSession.get_SharedSession()

We can clearly see that its trying to access local file system.

If the hosting is by renting a virtual machine this issue will not happen as we can give our code full access to the file system.

Root cause

If we look at the Evernote SDK source in Github, we can see it is caching the data/preferences in local file system. Currently there is no way to control that behavior. There is not even a way to provide our own provider.

Fix

Fix is simple. Need to get the Evernote SDK for .Net source code and refactor to have preference provider interface. Move current code into default file system based preference provider so that existing code will not break. For our special case of web hosting into Godaddy kind of servers, write new preference provider which is based on memory. 

Yes the performance may get affected due to app pool recycling and rebuilding of preference cache, but it will work in the web.

The fix is available in the below repository. A pull request is created, Evernote is yet to merge into their code base.

No comments: