…D when multiple concurrent requests are pending. Before the current commit ID was retrieved in the controller ctor but that could get out of date if the operation was waiting for another concurrent operation to complete. The impact of not having the most recent commit ID was that it forced a rebase -- now that is no longer the case.
…ntroller 1) Updated Mediatype mapping to to use System.Web.Mimemapping instead of the Windows registry. This makes the resulting mediatype consistent with other uses in System.Web and avoids looking at the registry. 2) Expand error message if we can't write to file system. Now we pass back the exception message (not the details) so that the caller has a better idea about what is going on. 3) Added tracer timer to git commands to get a better understanding of where time is going. 4) It turns out that "rebase" is very expensive so we now only use it when necessary. This shaves around 2 secs of each SCM VFS operation. 5) Avoided unnecessary calls to git in VFS SCM by reusing commit id 6) Avoid having "deploy" do a forced "get" in VFS SCM as we already know that the repo is up to date. This shaves 0.5 secs of each SCM VFS operation. 7) Added "nodeploy" and "message" query options to SCM VFS that enables us to add files without deploying and to customize the commit message. 8) Replaced ProgressWriter implementation with one that doesn't fire up a new thread. The overhead of the old implementation was 250 ms per operation (not just SCM VFS). Now there is no longer any measurable overhead. 9) Removed the exponential backoff and instead moved to an async lock model which is much more efficient and general purpose. 10) Addressed code review comments
…s last modified can not be reliably compared across different OSs. Create etag based on last modified time only instead of both LM and creation time.
…ultiple times but only doing the cleanup on the first time through. Avoided double-releasing the file lock on invalid range requests. Now we only release it once. Henrik
…tial backoff. Also, ensure that we do try after the last delay.
…ent scripts that sit outside the repository itself. Also added etag on successful delete requests as that allows a client to keep track of the latest etag when deleting as well as creating/updating content. Fixed bug where we did not deploy content in case of a merge. A test bug prevented us from discovering it. The test bug has also been fixed. Lastly, removed an extraneous row in exponential backoff numbers so we are back to 8 instead of 9.
…ory clean to avoid leftover unstaged files. Further edits: 1) Deal with deployment exceptions and return a special message if deployment fails. 2) Added deployment validation to tests. 3) Increased max exponential backoff value to avoid "busy" responses
1) Added more robust support for handling lock contention when multiple requests arrive at the same time. Now there is an pseudo-exponential back-off algorithm which tries multiple times getting a lock rather than giving up first time. 2) If lock cannot be obtained then return a 503 status code with a Retry-After header instead of a 409. This allows for the client to detect that it is a temporary situation and it may succeed if it retries. 3) Added support for wildcard match on DELETE and PUT. If an If-Match: * wildcard conditional request then we automatically set it to the current commit ID whatever that is. 4) Moved some of the Task stuff to .NET 4.5 so that we can use "await Task.Delay(...)". Henrik
1) Enabled support for wildcard etag. This allows the caller on PUT to use If-Match: * to match any exiting file. 2) Updated test to handle slash and turned on terminating slash for RemoteVfsManager 3) Added support for deleting empty directories. 4) Fixed bug in MediaTypeMap.GetMediaType not catching if we get a null registry key.
1) Updated HttpClientHelper to expose statics for creating an HttpClient and an HttpClientHandler which is correctly set up to handle authentication. It uses a CredentialsCache along with preauthentication which handles authentication across redirects. 2) Updated KuduRemoteClientBase to make not force a teminating "/" on the base URI. This makes it possible to VFS to use the client base. Also cleaned up the class so that it is easier to use, 3) Added RemoteVfsManager to ApplicationManager which correct base URI and credentials. 4) Updated places which created an HttpClientHandler manually to instead use HttpClientHelper.CreateClientHandler
1) VfsController -- general Kudu file browser. 2) LiveScmVfsController -- git backed file browser Both controllers provide version protected GET, PUT, and DELETE based on etag that avoids lost updates. VfsController is backed by the file system and LiveScmVfsController is backed by a git repository allowing for automatic rebasing and commits. Both controllers derive from VfsControllerBase but there are differences in how each manages access to the file system as well as handling conflicts. The common functionality is as follows: a) File and directory browsing: Directories are serialized in a JSON format and files are serialized with the proper content type b) File etag support: each version of a file has a different etag. The VfsController uses an etag based on the file creation + last modifed type and the LiveScmVfsController uses git commit IDs c) Range requests: It is possible to request ranges of files using the HTTP/1.1 Range header field in combination with the If-Range header indicating a paticular etag to get the ranges over. Note that this functionality will also be made available as a general Wbe API feature so it is only temporarily placed here. d) Automatic redirections where URIs pointing to directories but does not have a terminating "/" are automatically redirected to a URI that does. Similarly, URIs pointing to files but do haev a terminating "/" are automatically redirected to a URL that doesn't/ When ScmController updates a resource, the etag included in the If-Match header field is checked that it is present and then the file is updated. When LiveScmVfsController updates a resource, it first checks out a branch based on the commit ID on which the edit was based (sent in a If-Match header field). It then applies the edits and does a commit and rebase against main. If the rebase succeeds then it sends back a successful response. In case of conflicting updates, it sends back a 409 Conflict response including the conflict as reported by git so that the user can see it. An example of what this looks like is as follows: HTTP/1.1 409 Conflict Content-Length: 137 Content-Type: text/plain <<<<<<< HEAD abcdef 123456 ======= 123456 abcdef >>>>>>> Committing update from request http://localhost:6478/scmvfs/new/file.txt