return CompletedTask<object>.Default;
}
-
-/*
- private Task Process(Task<WorkflowState> action)
- {
- return action.ContinueWith(t => Process(t.Result));
- }
-*/
-
-
public bool Pause
{
get { return _watcher == null || !_watcher.EnableRaisingEvents; }
//Ignore events that affect the cache folder
var filePath = e.FullPath;
if (Ignore(filePath))
- return;
-
+ return;
+ if (Directory.Exists(filePath))
+ return;
_agent.Post(new WorkflowState{AccountInfo=AccountInfo, Path = filePath, FileName = e.Name, TriggeringChange = e.ChangeType });
}
break;
case CloudActionType.DownloadUnconditional:
- await DownloadCloudFile(accountInfo, cloudFile,downloadPath);
+ await DownloadCloudFile(accountInfo, cloudFile, downloadPath);
break;
case CloudActionType.DeleteCloud:
DeleteCloudFile(accountInfo, cloudFile);
case CloudActionType.MustSynch:
if (!File.Exists(downloadPath))
- {
+ {
await DownloadCloudFile(accountInfo, cloudFile, downloadPath);
}
else
Log.InfoFormat("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile,
action.CloudFile.Name);
}
+ catch (WebException exc)
+ {
+ Log.ErrorFormat("[WEB ERROR] {0} : {1} -> {2} due to exception\r\n{3}", action.Action, action.LocalFile, action.CloudFile, exc);
+ }
catch (OperationCanceledException)
{
throw;
if (task.IsFaulted)
{
//ListObjects failed at this point, need to reschedule
- Log.ErrorFormat("[FAIL] ListObjects for{0} in ProcessRemoteFiles with {0}", accountInfo.UserName,task.Exception);
+ Log.ErrorFormat("[FAIL] ListObjects for{0} in ProcessRemoteFiles with {1}", accountInfo.UserName,task.Exception);
return;
}
using (log4net.ThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
//Items with the same name, hash may be both in the container and the trash
//Don't delete items that exist in the container
var realTrash = from trash in trashObjects
- where !remoteObjects.Any(info => info.Hash == trash.Hash)
+ where !remoteObjects.Any(info => info.Name == trash.Name && info.Hash == trash.Hash)
select trash;
ProcessDeletedFiles(accountInfo,realTrash);
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
+using System.Data.SQLite;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using Pithos.Interfaces;
using Pithos.Network;
using log4net;
-using log4net.Appender;
-using log4net.Config;
-using log4net.Layout;
namespace Pithos.Core.Agents
{
{
action();
}
+ catch (SQLiteException ex)
+ {
+ Log.ErrorFormat("[ERROR] SQL \n{0}", ex);
+ }
catch (Exception ex)
{
- Log.ErrorFormat("[ERROR] STATE \n{0}",ex);
+ Log.ErrorFormat("[ERROR] STATE \n{0}", ex);
}
+// ReSharper disable AccessToModifiedClosure
queue.DoAsync(loop);
+// ReSharper restore AccessToModifiedClosure
});
};
loop();
{
//This is a new file
var fullPath = pair.File.FullName.ToLower();
- var createState = FileState.CreateForAsync(fullPath, this.BlockSize, this.BlockHash);
+ var createState = FileState.CreateForAsync(fullPath, BlockSize, BlockHash);
createState.ContinueWith(state => _persistenceAgent.Post(state.Result.Create));
}
else if (file == null)
//This file was deleted while we were down. We should mark it as deleted
//We have to go through UpdateStatus here because the state object we are using
//was created by a different ORM session.
- UpdateStatus(fileState.Id,state=> state.FileStatus = FileStatus.Deleted);
+ FileState.UpdateStatus(fileState.Id,FileStatus.Deleted);
}
else
{
//If the hashes don't match the file was changed
if (fileState.Checksum != hashString)
{
- UpdateStatus(fileState.Id, state => state.FileStatus = FileStatus.Modified);
+ FileState.UpdateStatus(fileState.Id, FileStatus.Modified);
}
}
});
}
- private string _pithosDataPath;
-
- public T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue )
- {
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path");
- if (!Path.IsPathRooted(path))
- throw new ArgumentException("path must be a rooted path", "path");
- if (getter == null)
- throw new ArgumentNullException("getter");
- Contract.EndContractBlock();
-
-
- try
- {
- var state = FileState.FindByFilePath(path);
- return state == null ? defaultValue : getter(state);
- }
- catch (Exception exc)
- {
- Log.ErrorFormat(exc.ToString());
- return defaultValue;
- }
- }
-
- /// <summary>
- /// Sets the status of a file, creating a new FileState entry if one doesn't already exist.
- /// </summary>
- /// <param name="path"></param>
- /// <param name="setter"></param>
- public void SetStatus(string path,Action<FileState> setter)
- {
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path", "path can't be empty");
- if (setter==null)
- throw new ArgumentNullException("setter", "setter can't be empty");
- Contract.EndContractBlock();
+ private readonly string _pithosDataPath;
- _persistenceAgent.Post(() =>
- {
- using (new SessionScope())
- {
- var filePath = path.ToLower();
- var state = FileState.FindByFilePath(filePath);
- if (state != null)
- {
- setter(state);
- state.Save();
- }
- else
- {
- state = new FileState {FilePath = filePath,Id=Guid.NewGuid()};
- setter(state);
- state.Save();
- }
- }
- });
- }
-
- /// <summary>
- /// Sets the status of a file only if the file already exists
- /// </summary>
- /// <param name="path"></param>
- /// <param name="setter"></param>
- private void UpdateStatus(string path, Action<FileState> setter)
- {
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path");
- if (!Path.IsPathRooted(path))
- throw new ArgumentException("The path must be rooted", "path");
- if (setter == null)
- throw new ArgumentNullException("setter");
- Contract.EndContractBlock();
-
- Debug.Assert(!path.Contains(FolderConstants.CacheFolder));
- Debug.Assert(!path.EndsWith(".ignore"));
-
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path", "path can't be empty");
-
- if (setter == null)
- throw new ArgumentNullException("setter", "setter can't be empty");
-
- _persistenceAgent.Post(() =>
- {
- using (new SessionScope())
- {
- var filePath = path.ToLower();
-
- var state = FileState.FindByFilePath(filePath);
- if (state == null)
- {
- Log.WarnFormat("[NOFILE] Unable to set status for {0}.", filePath);
- state = new FileState { FilePath = path, Id = Guid.NewGuid() };
- state.Create();
- }
- setter(state);
- state.Save();
- }
-
- });
- }
-
- /// <summary>
- /// Sets the status of a specific state
- /// </summary>
- /// <param name="path"></param>
- /// <param name="setter"></param>
- private void UpdateStatus(Guid stateID, Action<FileState> setter)
- {
- if (setter == null)
- throw new ArgumentNullException("setter");
- Contract.EndContractBlock();
-
-
- _persistenceAgent.Post(() =>
- {
- using (new SessionScope())
- {
- var state = FileState.Find(stateID);
- if (state == null)
- {
- Log.WarnFormat("[NOFILE] Unable to set status for {0}.", stateID);
- return;
- }
- setter(state);
- state.Save();
- }
-
- });
- }
public FileOverlayStatus GetFileOverlayStatus(string path)
{
try
{
- //var state = FileState.FindByFilePath(path);
- var st=from state in FileState.Queryable
- where state.FilePath == path.ToLower()
- select state.OverlayStatus; ;
- return st.FirstOrDefault(); // state == null ? FileOverlayStatus.Unversioned : state.OverlayStatus;
+ var status = from state in FileState.Queryable
+ where state.FilePath ==path.ToLower()
+ select state.OverlayStatus;
+ return status.Any()? status.First():FileOverlayStatus.Unversioned;
}
catch (Exception exc)
{
throw new ArgumentException("The path must be rooted","path");
Contract.EndContractBlock();
- SetStatus(path.ToLower(),s=>s.OverlayStatus=overlayStatus);
- }
-
- /*public void RemoveFileOverlayStatus(string path)
- {
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path");
- if (!Path.IsPathRooted(path))
- throw new ArgumentException("The path must be rooted", "path");
- Contract.EndContractBlock();
-
- _persistenceAgent.Post(() =>
- InnerRemoveFileOverlayStatus(path));
- }
-
- private static void InnerRemoveFileOverlayStatus(string path)
- {
- if (String.IsNullOrWhiteSpace(path))
- throw new ArgumentNullException("path");
- if (!Path.IsPathRooted(path))
- throw new ArgumentException("The path must be rooted", "path");
- Contract.EndContractBlock();
-
- FileState.DeleteByFilePath(path);
- }*/
-
- public void RenameFileOverlayStatus(string oldPath, string newPath)
- {
- if (String.IsNullOrWhiteSpace(oldPath))
- throw new ArgumentNullException("oldPath");
- if (!Path.IsPathRooted(oldPath))
- throw new ArgumentException("The oldPath must be rooted", "oldPath");
- if (String.IsNullOrWhiteSpace(newPath))
- throw new ArgumentNullException("newPath");
- if (!Path.IsPathRooted(newPath))
- throw new ArgumentException("The newPath must be rooted", "newPath");
- Contract.EndContractBlock();
-
- _persistenceAgent.Post(() =>
- InnerRenameFileOverlayStatus(oldPath, newPath));
+ _persistenceAgent.Post(() => FileState.StoreOverlayStatus(path.ToLower(),overlayStatus));
}
- private static void InnerRenameFileOverlayStatus(string oldPath, string newPath)
+ /* public void RenameFileOverlayStatus(string oldPath, string newPath)
{
if (String.IsNullOrWhiteSpace(oldPath))
throw new ArgumentNullException("oldPath");
throw new ArgumentException("The newPath must be rooted", "newPath");
Contract.EndContractBlock();
- var state = FileState.FindByFilePath(oldPath);
-
- if (state == null)
- {
- Log.WarnFormat("[NOFILE] Unable to set status for {0}.", oldPath);
- return;
- }
- //NOTE: This will cause problems if path is used as a key in relationships
- state.FilePath = newPath;
- state.Update();
- }
+ _persistenceAgent.Post(() =>FileState.RenameState(oldPath, newPath));
+ }*/
public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
{
throw new ArgumentException("The path must be rooted", "path");
Contract.EndContractBlock();
- checked HERE to fix conflicts
+ Debug.Assert(!path.Contains(FolderConstants.CacheFolder));
+ Debug.Assert(!path.EndsWith(".ignore"));
- UpdateStatus(path.ToLower(),state=>
- {
- state.FileStatus = fileStatus;
- state.OverlayStatus = overlayStatus;
- });
+ _persistenceAgent.Post(() => FileState.UpdateStatus(path.ToLower(), fileStatus, overlayStatus));
}
public void StoreInfo(string path,ObjectInfo objectInfo)
//Forgetting to use a sessionscope results in two sessions being created, one by
//FirstOrDefault and one by Save()
var state =FileState.FindByFilePath(filePath);
+
//Create a new empty state object if this is a new file
state = state ?? new FileState();
state.FileStatus = FileStatus.Unchanged;
state.OverlayStatus = FileOverlayStatus.Normal;
- //Create a list of tags from the ObjectInfo's tag dictionary
- //Make sure to bind each tag to its parent state so we don't have to save each tag separately
- //state.Tags = (from pair in objectInfo.Tags
- // select
- // new FileTag
- // {
- // FileState = state,
- // Name = pair.Key,
- // Value = pair.Value
- // }
- // ).ToList();
-
+
//Do the save
state.Save();
}
public void SetFileStatus(string path, FileStatus status)
- {
- UpdateStatus(path.ToLower(), state=>state.FileStatus = status);
+ {
+ if (String.IsNullOrWhiteSpace(path))
+ throw new ArgumentNullException("path");
+ if (!Path.IsPathRooted(path))
+ throw new ArgumentException("The path must be rooted", "path");
+ Contract.EndContractBlock();
+
+ _persistenceAgent.Post(() => FileState.UpdateStatus(path.ToLower(), status));
}
public FileStatus GetFileStatus(string path)
throw new ArgumentException("The path must be rooted", "path");
Contract.EndContractBlock();
- var state = FileState.FindByFilePath(path);
- return (state==null)?FileStatus.Missing:state.FileStatus ;
+ var status = from r in FileState.Queryable
+ where r.FilePath == path.ToLower()
+ select r.FileStatus;
+ return status.Any()?status.First(): FileStatus.Missing;
}
public void ClearFileStatus(string path)
if (!Path.IsPathRooted(path))
throw new ArgumentException("The path must be rooted", "path");
Contract.EndContractBlock();
-
- //TODO:SHOULDN'T need both clear file status and remove overlay status
- _persistenceAgent.Post(() =>
- {
- using (new SessionScope())
- {
- FileState.DeleteByFilePath(path);
- }
- });
+
+ _persistenceAgent.Post(() => FileState.DeleteByFilePath(path));
}
public void UpdateFileChecksum(string path, string checksum)
throw new ArgumentException("The path must be rooted", "path");
Contract.EndContractBlock();
- _persistenceAgent.Post(() =>
- {
- using (new SessionScope())
- {
- var state = FileState.FindByFilePath(path);
- if (state == null)
- {
- Log.WarnFormat("[NOFILE] Unable to set checkesum for {0}.", path);
- return;
- }
- state.Checksum = checksum;
- state.Update();
- }
- });
+ _persistenceAgent.Post(() => FileState.UpdateChecksum(path.ToLower(), checksum));
}
}
var accountInfo = state.AccountInfo;
using (log4net.ThreadContext.Stacks["Workflow"].Push("Process"))
{
- if (Log.IsDebugEnabled) Log.DebugFormat("State {0} {1} {2}", state.FileName,state.Status,state.TriggeringChange);
-
- if (state.Skip)
+ try
{
- if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}",state.FileName);
-
- return CompletedTask<object>.Default;
- }
- string path = state.Path.ToLower();
- //Bypass deleted files, unless the status is Deleted
- if (!File.Exists(path) && state.Status != FileStatus.Deleted)
- {
- state.Skip = true;
- this.StatusKeeper.ClearFileStatus(path);
-
- if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
+ if (Log.IsDebugEnabled)
+ Log.DebugFormat("State {0} {1} {2}", state.FileName, state.Status, state.TriggeringChange);
- return CompletedTask<object>.Default;
- }
+ if (state.Skip)
+ {
+ if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}", state.FileName);
+
+ return CompletedTask<object>.Default;
+ }
+ string path = state.Path.ToLower();
+
+ //Bypass deleted files, unless the status is Deleted
+ if (!File.Exists(path) && state.Status != FileStatus.Deleted)
+ {
+ state.Skip = true;
+ this.StatusKeeper.ClearFileStatus(path);
+
+ if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
+
+ return CompletedTask<object>.Default;
+ }
+
+ var fileState = FileState.FindByFilePath(path);
+ var info = new FileInfo(path);
- var fileState = FileState.FindByFilePath(path);
- var info = new FileInfo(path);
+ switch (state.Status)
+ {
+ case FileStatus.Created:
+ case FileStatus.Modified:
+ NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState, accountInfo.BlockSize,
+ accountInfo.BlockHash));
+ break;
+ case FileStatus.Deleted:
+ NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState));
+ break;
+ case FileStatus.Renamed:
+ NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud,
+ new FileInfo(state.OldPath),
+ new FileInfo(state.Path)));
+ break;
+ }
- switch (state.Status)
+ return CompletedTask<object>.Default;
+ }
+ catch (Exception ex)
{
- case FileStatus.Created:
- case FileStatus.Modified:
- NetworkAgent.Post(new CloudUploadAction(accountInfo,info, fileState, accountInfo.BlockSize,
- accountInfo.BlockHash));
- break;
- case FileStatus.Deleted:
- NetworkAgent.Post(new CloudDeleteAction(accountInfo,info, fileState));
- break;
- case FileStatus.Renamed:
- NetworkAgent.Post(new CloudMoveAction(accountInfo,CloudActionType.RenameCloud, new FileInfo(state.OldPath),
- new FileInfo(state.Path)));
- break;
+ Log.Error(ex.ToString());
+ throw;
}
-
- return CompletedTask<object>.Default;
}
}
var pendingStates = new List<WorkflowState>();
foreach (var state in pendingEntries)
{
- pendingStates.Add(new WorkflowState(account, state));
+ if (!Directory.Exists(state.FilePath))
+ pendingStates.Add(new WorkflowState(account, state));
}
if (Log.IsDebugEnabled)
Log.DebugFormat("Found {0} interrupted files", pendingStates.Count);
using System.Threading.Tasks;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
-using Castle.ActiveRecord.Queries;
-using NHibernate.Engine;
using Pithos.Core.Agents;
using Pithos.Interfaces;
-using Pithos.Network;
using log4net;
namespace Pithos.Core
using System;
using System.Collections.Generic;
using System.Linq;
- using System.Text;
/// <summary>
/// TODO: Update summary.
[Property]
public string Checksum { get; set; }
-/*
- [Property]
- public string TopHash { get; set; }
-*/
[Property]
public long? Version { get; set; }
set { _tags=value;}
}
-// [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
-// public IList<FileHash> Hashes { get; set; }
-
-// [Property]
-// public byte[] HashmapHash { get; set; }
-
+
public static FileState FindByFilePath(string absolutePath)
{
if (string.IsNullOrWhiteSpace(absolutePath))
throw new ArgumentNullException("absolutePath");
Contract.EndContractBlock();
- FileState.Execute((session, instance) =>
+ Execute((session, instance) =>
{
const string hqlDelete = "delete FileState where FilePath = :path";
var deletedEntities = session.CreateQuery(hqlDelete)
.SetString("path", absolutePath.ToLower())
.ExecuteUpdate();
- return null;
+ return deletedEntities;
},null);
}
+ public static void StoreFileStatus(string absolutePath, FileStatus newStatus)
+ {
+ if (string.IsNullOrWhiteSpace(absolutePath))
+ throw new ArgumentNullException("absolutePath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set FileStatus= :status where FilePath = :path ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("path", absolutePath.ToLower())
+ .SetEnum("status", newStatus)
+ .ExecuteUpdate();
+ if (updatedEntities == 0)
+ {
+ var newState = new FileState { FilePath = absolutePath, Id = Guid.NewGuid(), FileStatus = newStatus };
+ newState.CreateAndFlush();
+ }
+ return null;
+ }, null);
+
+ }
+
+ public static void StoreOverlayStatus(string absolutePath, FileOverlayStatus newStatus)
+ {
+ if (string.IsNullOrWhiteSpace(absolutePath))
+ throw new ArgumentNullException("absolutePath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set OverlayStatus= :status where FilePath = :path ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("path", absolutePath.ToLower())
+ .SetEnum("status", newStatus)
+ .ExecuteUpdate();
+ if (updatedEntities == 0)
+ {
+ var newState = new FileState { FilePath = absolutePath, Id = Guid.NewGuid(), OverlayStatus = newStatus };
+ newState.CreateAndFlush();
+ }
+ return null;
+ }, null);
+
+ }
+
+ public static void UpdateStatus(string absolutePath, FileStatus fileStatus, FileOverlayStatus overlayStatus)
+ {
+ if (string.IsNullOrWhiteSpace(absolutePath))
+ throw new ArgumentNullException("absolutePath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("path", absolutePath.ToLower())
+ .SetEnum("fileStatus", fileStatus)
+ .SetEnum("overlayStatus", overlayStatus)
+ .ExecuteUpdate();
+ return updatedEntities;
+ }, null);
+
+ }
+ public static void UpdateStatus(string absolutePath, FileStatus fileStatus)
+ {
+ if (string.IsNullOrWhiteSpace(absolutePath))
+ throw new ArgumentNullException("absolutePath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set FileStatus= :fileStatus where FilePath = :path ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("path", absolutePath.ToLower())
+ .SetEnum("fileStatus", fileStatus)
+ .ExecuteUpdate();
+ return updatedEntities;
+ }, null);
+
+ }
+
+ public static void RenameState(string oldPath, string newPath)
+ {
+ if (string.IsNullOrWhiteSpace(oldPath))
+ throw new ArgumentNullException("oldPath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set FilePath= :newPath where FilePath = :oldPath ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("oldPath", oldPath.ToLower())
+ .SetString("newPath", newPath.ToLower())
+ .ExecuteUpdate();
+ return updatedEntities;
+ }, null);
+
+ }
+
+ public static void UpdateStatus(Guid id, FileStatus fileStatus)
+ {
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set FileStatus= :fileStatus where Id = :id ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetGuid("id", id)
+ .SetEnum("fileStatus", fileStatus)
+ .ExecuteUpdate();
+ return updatedEntities;
+ }, null);
+
+ }
+
+ public static void UpdateChecksum(string absolutePath, string checksum)
+ {
+ if (string.IsNullOrWhiteSpace(absolutePath))
+ throw new ArgumentNullException("absolutePath");
+ Contract.EndContractBlock();
+
+ Execute((session, instance) =>
+ {
+ const string hqlUpdate = "update FileState set Checksum= :checksum where FilePath = :path ";
+ var updatedEntities = session.CreateQuery(hqlUpdate)
+ .SetString("path", absolutePath.ToLower())
+ .SetString("checksum", checksum)
+ .ExecuteUpdate();
+ return updatedEntities;
+ }, null);
+
+ }
+
public static void ChangeRootPath(string oldPath,string newPath)
{
if (String.IsNullOrWhiteSpace(oldPath))
{
const string hqlUpdate =
"update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
- var result=session.CreateQuery(hqlUpdate)
+ var renames=session.CreateQuery(hqlUpdate)
.SetString("oldPath", oldPath.ToLower())
.SetString("newPath", newPath.ToLower())
.ExecuteUpdate();
- return null;
+ return renames;
}, null);
}
}
public FileState FileState { get; set; }
}
-
- /* [ActiveRecord("hashes")]
- public class FileHash : ActiveRecordLinqBase<FileHash>
- {
- [PrimaryKey]
- public int Id { get; set; }
-
- [Property]
- public int Order { get; set; }
-
- [Property]
- public byte[] Value { get; set; }
-
- [BelongsTo("FileStateID")]
- public FileState FileState { get; set; }
-
- }*/
-
-
+
}
void Stop();
void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus);
void StoreInfo(string path, ObjectInfo objectInfo);
- T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue );
- void SetStatus(string path, Action<FileState> setter);
+ //T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue );
+ //void SetStatus(string path, Action<FileState> setter);
void StartProcessing(CancellationToken token);
throw new ArgumentNullException("path", "The path parameter must not be emtpy");
if (!Directory.Exists(path) && !File.Exists(path))
- throw new FileNotFoundException("The specified file or path does not exist", path);
+ return;
IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Dynamic;
using System.Globalization;
namespace Pithos.Interfaces
{
+ [DebuggerDisplay("Name {Name}")]
public class ObjectInfo:DynamicObject
{
private readonly List<string> _knownContainers= new List<string>{"trash"};
_extensions.TryGetValue(name, out value);
return value ;
}
-
+
private long? GetLong(string name)
{
string version;
}
- public Task<TreeHash> GetHashMap(string account, string container, string objectName)
+ public async Task<TreeHash> GetHashMap(string account, string container, string objectName)
{
if (String.IsNullOrWhiteSpace(container))
throw new ArgumentNullException("container");
//object to avoid concurrency errors.
//
//Download operations take a long time therefore they have no timeout.
- //TODO: Do we really? this is a hashmap operation, not a download
- var client = new RestClient(_baseClient) { Timeout = 0 };
- if (!String.IsNullOrWhiteSpace(account))
- client.BaseAddress = GetAccountUrl(account);
-
-
- //The container and objectName are relative names. They are joined with the client's
- //BaseAddress to create the object's absolute address
- var builder = client.GetAddressBuilder(container, objectName);
- builder.Query = "format=json&hashmap";
- var uri = builder.Uri;
+ //TODO: Do they really? this is a hashmap operation, not a download
//Start downloading the object asynchronously
- var downloadTask = client.DownloadStringTask(uri);
-
- //Once the download completes
- return downloadTask.ContinueWith(download =>
+ using (var client = new RestClient(_baseClient) { Timeout = 0 })
{
- //Delete the local client object
- client.Dispose();
- //And report failure or completion
- if (download.IsFaulted)
- {
- Log.ErrorFormat("[GET HASH] FAIL for {0} with \r{1}", objectName,
- download.Exception);
- throw download.Exception;
- }
-
- //The server will return an empty string if the file is empty
- var json = download.Result;
+ if (!String.IsNullOrWhiteSpace(account))
+ client.BaseAddress = GetAccountUrl(account);
+
+ //The container and objectName are relative names. They are joined with the client's
+ //BaseAddress to create the object's absolute address
+ var builder = client.GetAddressBuilder(container, objectName);
+ builder.Query = "format=json&hashmap";
+ var uri = builder.Uri;
+
+
+ var json = await client.DownloadStringTaskAsync(uri);
var treeHash = TreeHash.Parse(json);
- Log.InfoFormat("[GET HASH] END {0}", objectName);
+ Log.InfoFormat("[GET HASH] END {0}", objectName);
return treeHash;
- });
+ }
}
catch (Exception exc)
{
throw;
}
-
-
}
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Pithos.Setup.x86", "Pithos.Setup.x86\Pithos.Setup.x86.vdproj", "{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetworkTests", "Tests\NetworkTests\NetworkTests.csproj", "{052D04DA-28FE-471F-96FD-BC1E92BF2A54}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug All|Any CPU = Debug All|Any CPU
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|Mixed Platforms.ActiveCfg = Release
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x64.ActiveCfg = Release
{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x86.ActiveCfg = Release
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Any CPU.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x64.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Any CPU.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x64.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Any CPU.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x64.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.ActiveCfg = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.Build.0 = Debug|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Any CPU.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.Build.0 = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x64.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.Build.0 = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Any CPU.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.Build.0 = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x64.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.ActiveCfg = Release|x86
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
{E027200B-C26A-4877-BFD9-1A18CF5DF2F4} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
- {052D04DA-28FE-471F-96FD-BC1E92BF2A54} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
EndGlobalSection
EndGlobal