NewLife/Stardust

StarWeb上传文件,自动广播扩散到StarServer,测试通过
智能大石头 authored at 2025-12-15 20:39:40
07e1653
Tree
1 Parent(s) 41332d3
Summary: 7 changed files with 66 additions and 21 deletions.
Modified +1 -1
Modified +1 -1
Modified +6 -3
Modified +1 -1
Modified +49 -12
Modified +7 -2
Modified +1 -1
Modified +1 -1
diff --git a/Samples/TestA/TestA.csproj b/Samples/TestA/TestA.csproj
index a8d8dfc..62ec45e 100644
--- a/Samples/TestA/TestA.csproj
+++ b/Samples/TestA/TestA.csproj
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta0602" />
+    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta1139" />
   </ItemGroup>
 
 </Project>
Modified +1 -1
diff --git a/Samples/TestB/TestB.csproj b/Samples/TestB/TestB.csproj
index 8e75182..92e8983 100644
--- a/Samples/TestB/TestB.csproj
+++ b/Samples/TestB/TestB.csproj
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta0602" />
+    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta1139" />
   </ItemGroup>
 
 </Project>
Modified +6 -3
diff --git a/Stardust.Server/Services/FileStorageService.cs b/Stardust.Server/Services/FileStorageService.cs
index 7cc7ea2..8d63b37 100644
--- a/Stardust.Server/Services/FileStorageService.cs
+++ b/Stardust.Server/Services/FileStorageService.cs
@@ -1,6 +1,7 @@
 using System.Diagnostics;
 using NewLife;
 using NewLife.Caching;
+using NewLife.Log;
 using Stardust.Data.Deployment;
 using Stardust.Storages;
 
@@ -30,10 +31,9 @@ public static class FileStorageExtensions
 
 public class CubeFileStorage : DefaultFileStorage
 {
-    public CubeFileStorage(ICacheProvider cacheProvider)
+    public CubeFileStorage(ICacheProvider cacheProvider, ITracer tracer, ILog log)
     {
-        var cache = cacheProvider.Cache as Cache;
-        if (cache != null)
+        if (cacheProvider.Cache is Cache cache)
         {
             var clientId = $"{NetHelper.MyIP()}@{Process.GetCurrentProcess().Id}";
             NewFileBus = cache.GetEventBus<NewFileInfo>("NewFile", clientId);
@@ -43,6 +43,9 @@ public class CubeFileStorage : DefaultFileStorage
         NodeName = Environment.MachineName;
         RootPath = "../Uploads";
         DownloadUri = "/cube/file?id={Id}";
+
+        Tracer = tracer;
+        Log = log;
     }
 
     /// <summary>获取本地文件的元数据</summary>
Modified +1 -1
diff --git a/Stardust/Stardust.csproj b/Stardust/Stardust.csproj
index e3bdc63..147cd1a 100644
--- a/Stardust/Stardust.csproj
+++ b/Stardust/Stardust.csproj
@@ -125,7 +125,7 @@
     <PackageReference Include="NewLife.Remoting" Version="3.6.2025.1214-beta1229" />
   </ItemGroup>
   <ItemGroup>
-    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta0602" />
+    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta1139" />
   </ItemGroup>
 
 </Project>
Modified +49 -12
diff --git a/Stardust/Storages/DefaultFileStorage.cs b/Stardust/Storages/DefaultFileStorage.cs
index 9cadd44..5ef54a7 100644
--- a/Stardust/Storages/DefaultFileStorage.cs
+++ b/Stardust/Storages/DefaultFileStorage.cs
@@ -7,7 +7,7 @@ using NewLife.Serialization;
 namespace Stardust.Storages;
 
 /// <summary>分布式文件存储默认基类,用于编排文件同步流程。具体应用应继承并实现与存储相关的操作。</summary>
-public abstract class DefaultFileStorage : DisposeBase, IFileStorage
+public abstract class DefaultFileStorage : DisposeBase, IFileStorage, ILogFeature, ITracerFeature
 {
     #region 属性
     /// <summary>用于广播新文件消息的事件总线。</summary>
@@ -46,6 +46,8 @@ public abstract class DefaultFileStorage : DisposeBase, IFileStorage
     {
         if (Interlocked.Exchange(ref _initialized, 1) == 1) return;
 
+        WriteLog("初始化分布式文件存储,节点:{0}", NodeName);
+
         // 仅订阅,处理逻辑使用独立方法,避免捕获初始化的取消令牌
         NewFileBus?.Subscribe(OnNewFileInfoAsync);
         FileRequestBus?.Subscribe(OnFileRequestAsync);
@@ -98,16 +100,26 @@ public abstract class DefaultFileStorage : DisposeBase, IFileStorage
     /// <summary>处理新文件消息。</summary>
     protected virtual async Task OnNewFileInfoAsync(NewFileInfo info, IEventContext<NewFileInfo> context, CancellationToken cancellationToken)
     {
-        XTrace.WriteLine("新文件通知:{0}", info.ToJson());
+        var msg = info.ToJson();
+        using var span = Tracer?.NewSpan(nameof(OnNewFileInfoAsync), msg);
+        span?.Detach(info.TraceId);
+        WriteLog("新文件通知:{0}", msg);
 
-        // 默认忽略本节点自己发布的消息(除非需要自愈)
-        if (info.SourceNode.EqualIgnoreCase(NodeName)) return;
+        //// 默认忽略本节点自己发布的消息(除非需要自愈)
+        //if (info.SourceNode.EqualIgnoreCase(NodeName)) return;
 
         // 检查本地是否已有文件且哈希正确
         if (CheckLocalFile(info.Path, info.Hash)) return;
 
-        // 从源节点拉取文件数据
-        await FetchFileAsync(info, info.SourceNode, cancellationToken).ConfigureAwait(false);
+        try
+        {
+            // 从源节点拉取文件数据
+            await FetchFileAsync(info, info.SourceNode, cancellationToken).ConfigureAwait(false);
+        }
+        catch (Exception ex)
+        {
+            span?.SetError(ex, null);
+        }
     }
 
     /// <summary>通过应用自定义的传输方式(如HTTP接口)从指定源节点拉取文件数据。</summary>
@@ -116,17 +128,31 @@ public abstract class DefaultFileStorage : DisposeBase, IFileStorage
         if (file == null || file.Path.IsNullOrEmpty()) throw new ArgumentNullException(nameof(file));
 
         var url = DownloadUri;
+        if (file is NewFileInfo fi) url = fi.NodeAddress + url;
         url = url.Replace("{Id}", file.Id + "");
         url = url.Replace("{Name}", file.Name);
 
-        var fileName = RootPath.CombinePath(file.Path).GetFullPath();
+        var span = DefaultSpan.Current;
+        WriteLog("下载文件:{0},来源:{1}", file.Name, url);
+        try
+        {
+            var fileName = RootPath.CombinePath(file.Path).GetFullPath();
+
+            //todo: 获取源节点基地址,通过HTTP等方式拉取文件数据
+            var client = new HttpClient();
+            client.SetUserAgent();
+            if (file is NewFileInfo fileInfo && !fileInfo.NodeAddress.IsNullOrEmpty())
+                client.BaseAddress = new Uri(fileInfo.NodeAddress.Split(";")[0]);
 
-        //todo: 获取源节点基地址,通过HTTP等方式拉取文件数据
-        var client = new HttpClient();
-        if (file is NewFileInfo fileInfo && !fileInfo.NodeAddress.IsNullOrEmpty())
-            client.BaseAddress = new Uri(fileInfo.NodeAddress.Split(";")[0]);
+            await client.DownloadFileAsync(url, fileName, file.Hash, cancellationToken).ConfigureAwait(false);
 
-        await client.DownloadFileAsync(url, fileName, file.Hash, cancellationToken).ConfigureAwait(false);
+            WriteLog("下载文件:{0},成功:{1}", file.Name, url);
+        }
+        catch (Exception ex)
+        {
+            span?.SetError(ex);
+            WriteLog("下载文件:{0},异常:{1}", file.Name, ex.Message);
+        }
     }
     #endregion
 
@@ -214,4 +240,15 @@ public abstract class DefaultFileStorage : DisposeBase, IFileStorage
         };
     }
     #endregion
+
+    #region 日志
+    /// <summary>追踪器</summary>
+    public ITracer? Tracer { get; set; }
+
+    /// <summary>日志</summary>
+    public ILog Log { get; set; } = Logger.Null;
+
+    /// <summary>写日志</summary>
+    public void WriteLog(String format, params Object?[] args) => Log?.Info(format, args);
+    #endregion
 }
Modified +7 -2
diff --git a/Stardust/Storages/NewFileInfo.cs b/Stardust/Storages/NewFileInfo.cs
index a94cb59..f2ea8a2 100644
--- a/Stardust/Storages/NewFileInfo.cs
+++ b/Stardust/Storages/NewFileInfo.cs
@@ -1,9 +1,11 @@
-namespace Stardust.Storages;
+using NewLife.Log;
+
+namespace Stardust.Storages;
 
 /// <summary>
 /// 新文件消息:宣告指定附件在某个节点可用。
 /// </summary>
-public class NewFileInfo : IFileInfo
+public class NewFileInfo : IFileInfo, ITraceMessage
 {
     /// <summary>公共数据库中的附件ID。</summary>
     public Int64 Id { get; set; }
@@ -25,4 +27,7 @@ public class NewFileInfo : IFileInfo
 
     /// <summary>节点地址</summary>
     public String? NodeAddress { get; set; }
+
+    /// <summary>追踪标识</summary>
+    public String? TraceId { get; set; }
 }
Modified +1 -1
diff --git a/Test/Test.csproj b/Test/Test.csproj
index 9aea200..23c730a 100644
--- a/Test/Test.csproj
+++ b/Test/Test.csproj
@@ -33,7 +33,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta0602" />
+    <PackageReference Include="NewLife.Core" Version="11.9.2025.1215-beta1139" />
   </ItemGroup>
 
   <ItemGroup>