上传 心跳包处理

Uat_Study
hang 2023-05-16 10:32:53 +08:00
parent 43ef5bcdd9
commit 8875595012
2 changed files with 172 additions and 127 deletions

View File

@ -178,6 +178,8 @@ namespace IRaCIS.Core.Application.Contracts
public class PreArchiveDicomStudyCommand public class PreArchiveDicomStudyCommand
{ {
//public string StudyInstanceUid { get; set; }
[NotDefault] [NotDefault]
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
[NotDefault] [NotDefault]

View File

@ -21,7 +21,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
[ApiExplorerSettings(GroupName = "Image")] [ApiExplorerSettings(GroupName = "Image")]
public class StudyService : BaseService, IStudyService public class StudyService : BaseService, IStudyService
{ {
private static object lockCodeGenerate = new object(); private static object lockObj = new object();
private static readonly AsyncLock _mutex = new AsyncLock(); private static readonly AsyncLock _mutex = new AsyncLock();
private static readonly AsyncLock _mutex2 = new AsyncLock(); private static readonly AsyncLock _mutex2 = new AsyncLock();
@ -93,8 +93,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand) public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
{ {
//lock (lockObj)
//{
// if (_provider.Exists($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}"))
// {
// //---当前已有人正在上传和归档该检查!
// return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress"));
// }
// else
// {
// _provider.Set($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30));
// }
//}
var studyMonitor = new StudyMonitor() var studyMonitor = new StudyMonitor()
{ {
@ -111,7 +121,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload, IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload,
FileSize = preArchiveStudyCommand.FileSize, FileSize = preArchiveStudyCommand.FileSize,
FileCount = preArchiveStudyCommand.FileCount, FileCount = preArchiveStudyCommand.FileCount,
//FailedFileCount = preArchiveStudyCommand.FailedFileCount,
}; };
@ -123,123 +132,76 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
public IResponseOutput DicomUploadInprogress(Guid trialId, string studyInstanceUid)
{
_provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30));
return ResponseOutput.Ok();
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand)
{ {
var trialId = incommand.TrialId; try
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
studyMonitor.UploadFinishedTime = DateTime.Now;
studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.FailedFileCount = incommand.FailedFileCount;
studyMonitor.IsSuccess = true;
//上传
if (studyMonitor.IsDicomReUpload == false)
{ {
var study = _mapper.Map<DicomStudy>(incommand.Study); var trialId = incommand.TrialId;
using (await _mutex.LockAsync()) var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
studyMonitor.UploadFinishedTime = DateTime.Now;
studyMonitor.ArchiveFinishedTime = DateTime.Now;
studyMonitor.FailedFileCount = incommand.FailedFileCount;
studyMonitor.IsSuccess = true;
//上传
if (studyMonitor.IsDicomReUpload == false)
{ {
//查询数据库获取最大的Code 没有记录则为0 var study = _mapper.Map<DicomStudy>(incommand.Study);
var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
//获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增 using (await _mutex.LockAsync())
var cacheMaxCodeInt = _provider.Get<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value;
int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
study.Code = currentNextCodeInt;
study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30));
}
study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
study.TrialId = incommand.TrialId;
study.SiteId = incommand.SiteId;
study.SubjectId = incommand.SubjectId;
study.SubjectVisitId = incommand.SubjectVisitId;
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
SpecialArchiveStudyDeal(study);
await _dicomstudyRepository.AddAsync(study);
studyMonitor.StudyId = study.Id;
studyMonitor.StudyCode = study.StudyCode;
foreach (var seriesItem in incommand.Study.SeriesList)
{
var series = _mapper.Map<DicomSeries>(seriesItem);
series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString());
series.StudyId = study.Id;
series.TrialId = incommand.TrialId;
series.SiteId = incommand.SiteId;
series.SubjectId = incommand.SubjectId;
series.SubjectVisitId = incommand.SubjectVisitId;
await _dicomSeriesRepository.AddAsync(series);
foreach (var instanceItem in seriesItem.InstanceList)
{ {
var isntance = _mapper.Map<DicomInstance>(instanceItem); //查询数据库获取最大的Code 没有记录则为0
isntance.StudyId = study.Id; var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
isntance.SeriesId = series.Id;
isntance.TrialId = incommand.TrialId; //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
isntance.SiteId = incommand.SiteId; var cacheMaxCodeInt = _provider.Get<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value;
isntance.SubjectId = incommand.SubjectId;
isntance.SubjectVisitId = incommand.SubjectVisitId; int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
study.Code = currentNextCodeInt;
study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30));
await _dicomInstanceRepository.AddAsync(isntance);
} }
}
study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
study.TrialId = incommand.TrialId;
study.SiteId = incommand.SiteId;
study.SubjectId = incommand.SubjectId;
study.SubjectVisitId = incommand.SubjectVisitId;
} //特殊处理逻辑
else study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
{ SpecialArchiveStudyDeal(study);
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ; await _dicomstudyRepository.AddAsync(study);
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
//_mapper.Map(incommand.Study, study);
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
SpecialArchiveStudyDeal(study);
studyMonitor.StudyId = study.Id;
studyMonitor.StudyCode = study.StudyCode;
// 少了整个序列
//某个序列下少了instance foreach (var seriesItem in incommand.Study.SeriesList)
foreach (var seriesItem in incommand.Study.SeriesList)
{
var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
//判断重复
if (dicomSeries == null)
{ {
var series = _mapper.Map<DicomSeries>(seriesItem); var series = _mapper.Map<DicomSeries>(seriesItem);
series.Id = seriesId; series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString());
series.StudyId = study.Id; series.StudyId = study.Id;
series.TrialId = incommand.TrialId; series.TrialId = incommand.TrialId;
@ -247,49 +209,120 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
series.SubjectId = incommand.SubjectId; series.SubjectId = incommand.SubjectId;
series.SubjectVisitId = incommand.SubjectVisitId; series.SubjectVisitId = incommand.SubjectVisitId;
await _dicomSeriesRepository.AddAsync(series);
dicomSeries = await _dicomSeriesRepository.AddAsync(series); foreach (var instanceItem in seriesItem.InstanceList)
{
var isntance = _mapper.Map<DicomInstance>(instanceItem);
isntance.StudyId = study.Id;
isntance.SeriesId = series.Id;
//新的序列 那么 检查的序列数量+1 isntance.TrialId = incommand.TrialId;
study.SeriesCount += 1; isntance.SiteId = incommand.SiteId;
isntance.SubjectId = incommand.SubjectId;
isntance.SubjectVisitId = incommand.SubjectVisitId;
await _dicomInstanceRepository.AddAsync(isntance);
}
} }
else
}
else
{
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ;
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
//_mapper.Map(incommand.Study, study);
//特殊处理逻辑
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
SpecialArchiveStudyDeal(study);
// 少了整个序列
//某个序列下少了instance
foreach (var seriesItem in incommand.Study.SeriesList)
{ {
//该序列掉了instance var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
dicomSeries.InstanceCount += seriesItem.InstanceCount;
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
//判断重复
if (dicomSeries == null)
{
var series = _mapper.Map<DicomSeries>(seriesItem);
series.Id = seriesId;
series.StudyId = study.Id;
series.TrialId = incommand.TrialId;
series.SiteId = incommand.SiteId;
series.SubjectId = incommand.SubjectId;
series.SubjectVisitId = incommand.SubjectVisitId;
dicomSeries = await _dicomSeriesRepository.AddAsync(series);
//新的序列 那么 检查的序列数量+1
study.SeriesCount += 1;
}
else
{
//该序列掉了instance
dicomSeries.InstanceCount += seriesItem.InstanceCount;
}
dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath;
foreach (var instanceItem in seriesItem.InstanceList)
{
var insntance = _mapper.Map<DicomInstance>(instanceItem);
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString());
insntance.StudyId = study.Id;
insntance.SeriesId = dicomSeries.Id;
insntance.TrialId = incommand.TrialId;
insntance.SiteId = incommand.SiteId;
insntance.SubjectId = incommand.SubjectId;
insntance.SubjectVisitId = incommand.SubjectVisitId;
await _dicomInstanceRepository.AddAsync(insntance);
}
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
study.InstanceCount += seriesItem.InstanceCount;
} }
dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath;
foreach (var instanceItem in seriesItem.InstanceList)
{
var insntance = _mapper.Map<DicomInstance>(instanceItem);
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString());
insntance.StudyId = study.Id;
insntance.SeriesId = dicomSeries.Id;
insntance.TrialId = incommand.TrialId;
insntance.SiteId = incommand.SiteId;
insntance.SubjectId = incommand.SubjectId;
insntance.SubjectVisitId = incommand.SubjectVisitId;
await _dicomInstanceRepository.AddAsync(insntance);
}
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
study.InstanceCount += seriesItem.InstanceCount;
} }
using (await _mutex2.LockAsync())
{
await _dicomInstanceRepository.SaveChangesAsync();
}
} }
catch (Exception ex)
using (await _mutex2.LockAsync())
{ {
await _dicomInstanceRepository.SaveChangesAsync();
return ResponseOutput.NotOk(ex.Message);
} }
finally
{
_provider.Remove($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}");
}
@ -729,7 +762,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var result = new VerifyStudyUploadResult(); var result = new VerifyStudyUploadResult();
if (_provider.Exists("StudyUid_" + studyInstanceUid)) if (_provider.Exists($"StudyUid_{trialId}_{studyInstanceUid}"))
{ {
result.AllowUpload = false; result.AllowUpload = false;
@ -790,6 +823,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
} }
result.StudyInstanceUid = studyInstanceUid; result.StudyInstanceUid = studyInstanceUid;
if (result.AllowReUpload || result.AllowUpload)
{
lock (lockObj)
{
_provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromMinutes(30));
}
}
return result; return result;
} }