The name brand does not appear to exist in .NET Framework, which is not receiving further features.
Net 5 migration #3124 is being worked on, but seems to need a lot of changes to be ready to release.
Duplicati developers have been moving away from “helper” libraries as standard capabilities emerge,
e.g. 2.0.5.1 Beta uses Long Path Support (MAXPATH
) done in .NET Framework 4.6.2 and mono 5.0.0.
I guess that there are sometimes fine points that should be considered, but I’m not qualified to do that.
CoCoL: Concurrent Communications Library and related papers does some in-depth analysis of this.
Let me post a draft of a note I started about a year that attempts to trace the summary to source code:
https://forum.duplicati.com/t/alternative-ftp-failure/7822/10
In Duplicati, this is used to enabled concurrency for hashing and compressing.
Roughly the following happens:
A process traverses the file system and writes paths to a channel
Maybe FileEnumerationProcess.cs
A process reads paths and checks if the metadata has changed; all changed paths are written to another channel
Maybe MetadataPreProcess.cs
Multiple processes read paths and computes block hashes; new block hashes (and data) are written to a channel
Maybe StreamBlockSplitter.cs
Multiple processes read blocks and compresses blocks; filled volumes are written as upload requests
Maybe DataBlockProcessor.cs
A process caps the number of active uploads
Maybe https://github.com/duplicati/duplicati/blob/63ecd1a49ff66acbd0335044ecb360c73a218468/Duplicati/Library/Main/Operation/Backup/BackendUploader.cs#L196-L199
A process performs the spill pickup (as described above)
Maybe SpillCollectorProcess.cs
A process performs the remote operations (upload, download, list)
Maybe BackendUploader.cs
https://github.com/duplicati/duplicati/blob/master/Duplicati/Library/Main/Operation/BackupHandler.cs
{
Backup.DataBlockProcessor.Run(database, options, taskreader),
Backup.FileBlockProcessor.Run(snapshot, options, database, stats, taskreader, token),
Backup.StreamBlockSplitter.Run(options, database, taskreader),
Backup.FileEnumerationProcess.Run(sources, snapshot, journalService,
options.FileAttributeFilter, sourcefilter, filter, options.SymlinkPolicy,
options.HardlinkPolicy, options.ExcludeEmptyFolders, options.IgnoreFilenames,
options.ChangedFilelist, taskreader, token),
Backup.FilePreFilterProcess.Run(snapshot, options, stats, database),
Backup.MetadataPreProcess.Run(snapshot, options, database, lastfilesetid, token),
Backup.SpillCollectorProcess.Run(options, database, taskreader),
Backup.ProgressHandler.Run(result)
}
// Spawn additional block hashers
.Union(
Enumerable.Range(0, options.ConcurrencyBlockHashers - 1).Select(x =>
Backup.StreamBlockSplitter.Run(options, database, taskreader))
)
// Spawn additional compressors
.Union(
Enumerable.Range(0, options.ConcurrencyCompressors - 1).Select(x =>
Backup.DataBlockProcessor.Run(database, options, taskreader))
)
Duplicati\Library\Main\Operation\Backup\FileEnumerationProcess.cs
Output = Backup.Channels.SourcePaths.ForWrite
Duplicati\Library\Main\Operation\Backup\CountFilesHandler.cs
Input = Backup.Channels.SourcePaths.ForRead
Duplicati\Library\Main\Operation\Backup\MetadataPreProcess.cs
Input = Backup.Channels.SourcePaths.ForRead,
StreamBlockChannel = Channels.StreamBlock.ForWrite,
Output = Backup.Channels.ProcessedFiles.ForWrite,
Duplicati\Library\Main\Operation\Backup\FilePreFilterProcess.cs
Input = Channels.ProcessedFiles.ForRead,
Output = Channels.AcceptedChangedFile.ForWrite
Duplicati\Library\Main\Operation\Backup\FileBlockProcessor.cs
Input = Channels.AcceptedChangedFile.ForRead,
StreamBlockChannel = Channels.StreamBlock.ForWrite,
(multiple)
Duplicati\Library\Main\Operation\Backup\StreamBlockSplitter.cs
Input = Channels.StreamBlock.ForRead,
ProgressChannel = Channels.ProgressEvents.ForWrite,
BlockOutput = Channels.OutputBlocks.ForWrite
(multiple)
Duplicati\Library\Main\Operation\Backup\DataBlockProcessor.cs
Input = Channels.OutputBlocks.ForRead,
Output = Channels.BackendRequest.ForWrite,
SpillPickup = Channels.SpillPickup.ForWrite,
Duplicati\Library\Main\Operation\Backup\SpillCollectorProcess.cs
Input = Channels.SpillPickup.ForRead,
Output = Channels.BackendRequest.ForWrite,
Duplicati\Library\Main\Operation\Backup\RecreateMissingIndexFiles.cs
UploadChannel = Channels.BackendRequest.ForWrite
Duplicati\Library\Main\Operation\Backup\BackendUploader.cs
Input = Channels.BackendRequest.ForRead,
This was done just by tracing Channels references in source. I don’t do pictures well, so there are none.
If a conversion to a new way happens, it would be nice to improve the documentation while sorting it out.