libgit2 / libgit2/libgit2sharp
Parallel calls to Repository.ObjectDatabase.CreateBlob with identical contents fails.
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- C#
- Star
- 3.5k
- Fork
- 925
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
I would like to insert blobs from memory into an object database in parallel (based on the technique described at http://stackoverflow.com/a/16244234). This works fine most of the time, but is subject to race conditions if the contents are the same. There are two classes of errors I observe:
1. Exception due to FILE_EXISTS conflict when trying to create the directory with the first two characters of the OID under objects.
2. NULL blob returned from CreateBlob.
Here's some example code to reproduce the problem:
using System;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using LibGit2Sharp;
namespace GitODBStress
{
class Program
{
static void Main()
{
string repoPath = Path.Combine(Path.GetTempPath(), "Git_Parallel_Odb");
int iterationCount = 100;
if (!Directory.Exists(repoPath))
{
Directory.CreateDirectory(repoPath);
}
var path = Repository.Init(repoPath, isBare:true);
Console.WriteLine("Made repo at {0}", path);
var repo = new Repository(path);
var tasks = new Task[2];
for (int i = 0; i < iterationCount; ++i)
{
var iter = i;
byte[] buf = Encoding.ASCII.GetBytes("foo" + iter.ToString());
for (int taskNo = 0; taskNo < 2; ++taskNo)
{
tasks[taskNo] = Task.Factory.StartNew(() =>
{
MemoryStream ms = new MemoryStream(buf);
for (; ; )
{
try
{
var blob = repo.ObjectDatabase.CreateBlob(ms);
if (blob == null)
{
Console.WriteLine("ERROR: NULL blob on iteration {0}", iter);
continue;
}
break;
}
catch (LibGit2SharpException e)
{
Console.WriteLine("ERROR: Caught LibGit2SharpException on iteration {0}: {1}", iter, e.Message);
if (e.Message.Contains("Cannot create a file when that file already exists."))
{
continue;
}
}
}
});
}
Task.WaitAll(tasks);
}
repo.Dispose();
// clean up temp repo files
var files = Directory.GetFiles(repoPath, "*.*", SearchOption.AllDirectories);
foreach (var f in files)
{
var attrib = File.GetAttributes(f);
if (attrib.HasFlag(FileAttributes.ReadOnly))
{
File.SetAttributes(f, attrib & ~FileAttributes.ReadOnly);
}
}
Directory.Delete(repoPath, true);
}
}
}
Thanks!
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu tại Repository.ObjectDatabase.CreateBlob và chạy bản tái hiện bằng C# trên một bare repository. Truy vết đường dẫn song song cho các nội dung giống hệt nhau và các kết quả FILE_EXISTS và null-blob đã được báo cáo. Hoàn thành khi các lệnh gọi đồng thời kết thúc mà không gặp một trong hai lỗi và tạo ra blob ожидаợi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- csharp, git
- Lĩnh vực
- databases
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 35/100