1+ using System ;
2+ using dotnetCampus . Ipc . Context ;
3+ using dotnetCampus . Ipc . IpcRouteds . DirectRouteds ;
4+ using dotnetCampus . Ipc . Pipes ;
5+ using dotnetCampus . Ipc . Threading ;
6+ using dotnetCampus . Ipc . Utils . Buffers ;
7+
8+ using DotNetCampus . Cli ;
9+ using DotNetCampus . Cli . Compiler ;
10+ using DotNetCampus . MediaConverters . Contexts ;
11+ using DotNetCampus . MediaConverters . Contexts . IpcContexts ;
12+
13+ using System . Buffers ;
14+ using System . IO ;
15+ using System . Threading ;
16+ using System . Threading . Tasks ;
17+
18+ namespace DotNetCampus . MediaConverters . CommandLineHandlers ;
19+
20+ public class IpcHandler : ICommandHandler
21+ {
22+ [ Option ]
23+ public required string IpcName { get ; init ; }
24+
25+ /// <summary>
26+ /// 总的工作路径,可用在后续的转换过程中,存放日志或过程文件等
27+ /// </summary>
28+ [ Option ]
29+ public required string WorkingFolder { get ; init ; }
30+
31+ [ Option ]
32+ public bool ? ShouldLogToConsole { get ; init ; }
33+
34+ [ Option ]
35+ public bool ? ShouldLogToFile { get ; init ; }
36+
37+ public async Task < int > RunAsync ( )
38+ {
39+ var ipcConfiguration = new IpcConfiguration ( )
40+ {
41+ AutoReconnectPeers = false ,
42+ IpcLoggerProvider = name => new MediaConverterIpcLogger ( name , this ) ,
43+
44+ // 以下为默认配置
45+ SharedArrayPool = new SharedArrayPool ( ArrayPool < byte > . Shared ) ,
46+ IpcTaskScheduling = IpcTaskScheduling . GlobalConcurrent ,
47+ } ;
48+ ipcConfiguration . UseSystemJsonIpcObjectSerializer ( MediaConverterJsonSerializerSourceGenerationContext . Default ) ;
49+
50+ var ipcProvider = new IpcProvider ( IpcName , ipcConfiguration ) ;
51+
52+ var ipcHandlerLogger = new IpcHandlerLogger ( this ) ;
53+ var exitTaskCompletionSource = new TaskCompletionSource < int > ( ) ;
54+
55+ var jsonIpcDirectRoutedProvider = new JsonIpcDirectRoutedProvider ( ipcProvider ) ;
56+
57+ jsonIpcDirectRoutedProvider . AddRequestHandler ( IpcPaths . RequestConvertImage , async ( IpcConvertImageRequest request ) =>
58+ {
59+ if ( request . InputFile is null || request . OutputFile is null || request . ConvertConfigurationFile is null )
60+ {
61+ return IpcConvertImageResponse . FromErrorCode ( MediaConverterErrorCode . InvalidIpcRequestArgument ) ;
62+ }
63+
64+ var traceId = request . TraceId ?? Guid . NewGuid ( ) . ToString ( ) ;
65+
66+ var workingFolder = request . WorkingFolder ;
67+ if ( string . IsNullOrEmpty ( workingFolder ) )
68+ {
69+ workingFolder = Path . Join ( WorkingFolder , traceId ) ;
70+ }
71+
72+ Directory . CreateDirectory ( workingFolder ) ;
73+
74+ ipcHandlerLogger . LogMessage ( $ "[{ traceId } ] Receive RequestConvertImage. InputFile='{ request . InputFile } ' OutputFile='{ request . OutputFile } ' ConvertConfigurationFile='{ request . ConvertConfigurationFile } ' WorkingFolder='{ workingFolder } '") ;
75+
76+ var convertHandler = new ConvertHandler ( )
77+ {
78+ InputFile = request . InputFile ,
79+ OutputFile = request . OutputFile ,
80+ ConvertConfigurationFile = request . ConvertConfigurationFile ,
81+ WorkingFolder = workingFolder ,
82+ ShouldLogToConsole = ShouldLogToConsole ,
83+ ShouldLogToFile = ShouldLogToFile ,
84+ } ;
85+
86+ var errorCode = await Program . RunAsync ( convertHandler ) ;
87+ ipcHandlerLogger . LogMessage ( $ "[{ traceId } ] RequestConvertImage completed. ErrorCode={ errorCode . Code } Message={ errorCode . Message } ") ;
88+ return IpcConvertImageResponse . FromErrorCode ( errorCode ) ;
89+ } ) ;
90+
91+ jsonIpcDirectRoutedProvider . AddRequestHandler ( IpcPaths . Exit , ( IpcExitRequest request ) =>
92+ {
93+ ipcHandlerLogger . LogMessage ( $ "Request Exit. Code={ request . ExitCode } Reason={ request . Reason } ") ;
94+
95+ Task . Run ( async ( ) =>
96+ {
97+ await Task . Delay ( TimeSpan . FromSeconds ( 1 ) ) ;
98+ exitTaskCompletionSource . SetResult ( request . ExitCode ) ;
99+ } ) ;
100+
101+ return new IpcExitResponse ( )
102+ {
103+ Code = MediaConverterErrorCode . Success . Code ,
104+ Message = MediaConverterErrorCode . Success . Message
105+ } ;
106+ } ) ;
107+
108+ jsonIpcDirectRoutedProvider . StartServer ( ) ;
109+ return await exitTaskCompletionSource . Task ;
110+ }
111+ }
112+
113+ file class IpcHandlerLogger
114+ {
115+ public IpcHandlerLogger ( IpcHandler ipcHandler )
116+ {
117+ _ipcHandler = ipcHandler ;
118+
119+ CanLog = _ipcHandler . ShouldLogToConsole is true || _ipcHandler . ShouldLogToFile is true ;
120+
121+ if ( _ipcHandler . ShouldLogToFile is true )
122+ {
123+ var logFile = Path . Join ( _ipcHandler . WorkingFolder , "Log.txt" ) ;
124+ _logFile = new FileInfo ( logFile ) ;
125+ }
126+ }
127+
128+ private readonly FileInfo ? _logFile ;
129+ private readonly IpcHandler _ipcHandler ;
130+ private readonly Lock _locker = new Lock ( ) ;
131+
132+ private bool CanLog { get ; }
133+
134+ public void LogMessage ( string message )
135+ {
136+ if ( ! CanLog )
137+ {
138+ return ;
139+ }
140+
141+ if ( _ipcHandler . ShouldLogToConsole is true )
142+ {
143+ Console . WriteLine ( message ) ;
144+ }
145+
146+ if ( _logFile is { } logFile )
147+ {
148+ var logMessage = $ "[{ DateTime . Now : yyyy-MM-dd HH:mm:ss,fff} ] { message } ";
149+ lock ( _locker )
150+ {
151+ File . AppendAllLines ( logFile . FullName , [ logMessage ] ) ;
152+ }
153+ }
154+ }
155+ }
0 commit comments