프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / ConvertService / ServiceBase / Markus.Service.Station / StationService / ServiceStationTask.cs @ ff4b1e6e

이력 | 보기 | 이력해설 | 다운로드 (14 KB)

1 53c9637d taeseongkim
using Markus.Service.Interface;
2
using Markus.Message;
3
using System;
4
using System.Collections.Generic;
5
using System.Diagnostics;
6
using System.Linq;
7
using System.Text;
8
using System.Threading;
9
using System.Threading.Tasks;
10
using System.Management;
11
using static Markus.Service.Extensions.Encrypt;
12
using Markus.Service.Extensions;
13
using Markus.Service.Helper;
14
15
namespace Markus.Service
16
{
17
    /// <summary>
18
    /// 컨버터 큐 처리 
19
    /// </summary>
20
    public partial class ServiceStation
21
    {
22
        /// <summary>
23
        /// 컨버터 실행중인 item
24
        /// </summary>
25
        private static List<ConvertItem> AliveConvertQueue = new List<ConvertItem>();
26
27
        /// <summary>
28
        /// 컨버터 프로세스 실행
29
        /// </summary>
30
        /// <param name="convertitem"></param>
31
        public bool ConvertProcessStart(ConvertItem convertitem)
32
        {
33
            bool result = false;
34
            try
35
            {
36
           
37
                Process ConvertProcess = new Process();
38
39
                ProcessContext processSendData = new ProcessContext
40
                {
41
                    ConvertID = convertitem.ConvertID,
42
                    ConnectionString = MarkusDBConnectionString,
43
                    ServiceStationUri = gServiceHostAddress.ToString(),
44
                    OriginFilePath = convertitem.OriginfilePath,
45
                    SaveDirectory = convertitem.ConvertPath,
46
                    TempDirectory = DownloadTempFolder,
47 8feb21df taeseongkim
                    ReleaseWorkMemory = ReleaseWorkMemory,
48 53c9637d taeseongkim
                    MultiThreadMaxPages = MultiThreadMaxPages,
49
                    MinFontSize = MinFontSize,
50 2091a7e5 taeseongkim
                    SendStatusInterval = SaveStatusInterval,
51
                    UseResolution = UseResolution
52 53c9637d taeseongkim
                };
53
54
                var sendData = ObjectToBytesStringConvert.ObjectToBytesString(processSendData);
55
                
56
                ProcessStartInfo startInfo = new ProcessStartInfo
57
                {
58
                    UseShellExecute = false,
59
                    FileName = "Markus.Service.ConvertProcess.exe",
60
                    WindowStyle = ProcessWindowStyle.Hidden,
61
                    CreateNoWindow = true,
62
                    ErrorDialog = false,
63
                    RedirectStandardError = false,
64
                    Arguments = $"{convertitem.ConvertID.ToString()} {AESEncrypter.Encrypt(sendData)}"
65
                    //Arguments = $"{convertitem.ConvertID.ToString()} {convertitem.ProjectNumber} {AESEncrypter.Encrypt(MarkusDBConnectionString)} {gServiceHostAddress} {DownloadTempFolder} {MultiThreadMaxPages}"
66
                };
67
68
                ConvertProcess.StartInfo = startInfo;
69
                ConvertProcess.EnableRaisingEvents = false;
70
71
                System.Diagnostics.Debug.WriteLine("convert process run : " + startInfo.Arguments);
72
73
74
                if (ConvertProcess.Start())
75
                {
76
                    try
77
                    {
78
                        var processAffinity = ProcessorAffinityList.Except(AliveConvertQueue.Select(f => (long)f.ProcessorAffinity));
79
80
                        if (processAffinity.Count() > 0)
81
                        {
82
                            convertitem.ProcessorAffinity = processAffinity.First();
83
84
                            //int bitMask = 1 << (convertitem.ProcessorAffinity - 1);
85
                            //bitMask |= 1 << (anotherUserSelection - 1); / //  프로세스 두개 이상 선택
86
87
                            ConvertProcess.ProcessorAffinity = new IntPtr(convertitem.ProcessorAffinity);
88
89
                        }
90
                        else
91
                        {
92
                            // 모두 사용중일때 점유율이 작은 걸로 사용
93
                            var CurrentProcessAffinity = AliveConvertQueue.Select(f =>f.ProcessorAffinity).Distinct();
94
95
                            var affinity = CurrentProcessAffinity.Min();
96
97
                            convertitem.ProcessorAffinity = affinity;
98
                            ConvertProcess.ProcessorAffinity = new IntPtr(affinity);
99
                        }
100
                    }
101
                    catch (Exception ex)
102
                    {
103
                        System.Diagnostics.Debug.WriteLine(ex);
104
                    }
105
        
106
107
                    ServiceStation.AliveConvertQueue.Add(convertitem);
108
                    result = true;
109
                }
110
            }
111
            catch (Exception ex)
112
            {
113
                throw new Exception("ConvertThread " + $"{convertitem.ConvertID.ToString()} {convertitem.ProjectNumber} {AESEncrypter.Encrypt(MarkusDBConnectionString)} {gServiceHostAddress} {DownloadTempFolder} {MultiThreadMaxPages}", ex.InnerException);
114
            }
115
            finally
116
            {
117
                //GC.WaitForPendingFinalizers();
118
                //GC.Collect(2);
119
                //GC.Collect(2);
120
            }
121
122
            return result;
123
        }
124 0157b158 taeseongkim
    
125 53c9637d taeseongkim
        /// <summary>
126
        /// DB에 있는 대기중인 Item을 가져온다.
127
        /// </summary>
128
        public void setDataBaseWaitingList()
129
        {
130 0157b158 taeseongkim
            using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
131 53c9637d taeseongkim
            {
132 06f13e11 taeseongkim
                var convertItems = database.GetWaitConvertItems(this.RunProjectList, StationServiceList.Where(x=>x.IsOnline).Sum(f=>f.Properties.PROCESS_COUNT));
133 0157b158 taeseongkim
134
                foreach (var convert in convertItems)
135 53c9637d taeseongkim
                {
136 ff4b1e6e taeseongkim
                    //ReflashSubService();
137
138 0157b158 taeseongkim
                    if (convert.STATUS > (int)StatusCodeType.None)
139
                    {
140
                        database.SetCleanUpItem(convert.ID);
141
                    }
142
143 0a89a17f taeseongkim
                    PassConvertItem(convert.PROJECT_NO, convert.ID,convert.DOCUMENT_ID);
144 53c9637d taeseongkim
                }
145
            }
146 0157b158 taeseongkim
        }
147 53c9637d taeseongkim
148 ff4b1e6e taeseongkim
        public bool IsDataBaseWaitingList(int overListCount)
149
        {
150
            bool result = false;
151
152
            try
153
            {
154
                using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
155
                {
156
                    var convertItems = database.GetWaitConvertItems(this.RunProjectList, overListCount);
157
158
                    if (convertItems.Count() > 0)
159
                    {
160
                        result = true;
161
                    }
162
                }
163
            }
164
            catch (Exception ex)
165
            {
166
                logger.Error($"IsDataBaseWaitingList Error",ex);
167
            }
168
169
            return result;
170
        }
171
172
        private async void ReflashSubService()
173 0157b158 taeseongkim
        {
174 6f6e7dbf taeseongkim
            foreach (var subservice in StationServiceList)
175 0157b158 taeseongkim
            {
176
                try
177
                {
178 06f13e11 taeseongkim
                    subservice.IsOnline = SytemNet.Ping(subservice.Properties.SERVICE_ADDRESS);
179 0157b158 taeseongkim
180 06f13e11 taeseongkim
                    if (subservice.IsOnline)
181
                    {
182 ff4b1e6e taeseongkim
                        var result = await subservice.Service.AliveConvertListAsync();
183 06f13e11 taeseongkim
184
                        subservice.ConvertItems = result.ToList();
185
                        subservice.AliveCount = result.Count();
186
                    }
187
                    else
188
                    {
189
                        logger.Error($"Connection Error {subservice.Properties.SERVICE_ADDRESS}");
190 ff4b1e6e taeseongkim
                        subservice.ConvertItems = new List<WcfClient.StationServiceTask.ConvertItem>();
191 06f13e11 taeseongkim
                        subservice.AliveCount = subservice.Properties.PROCESS_COUNT;
192
                    }
193 0157b158 taeseongkim
                }
194
                catch (Exception ex)
195
                {
196 6f6e7dbf taeseongkim
                    logger.Error($"ReflashSubService error - Service ID : {subservice.Properties.ID} ", ex);
197
                }
198
            }
199
        }
200
201 06f13e11 taeseongkim
202 0a89a17f taeseongkim
        /// <summary>
203
        /// 
204
        /// </summary>
205
        /// <param name="ProjectNo"></param>
206
        /// <param name="ConvertID"></param>
207
        /// <param name="UniqueKey">Document ID(문서의 유일키)</param>
208 ff4b1e6e taeseongkim
        private async void PassConvertItem(string ProjectNo,string ConvertID,string UniqueKey)
209 6f6e7dbf taeseongkim
        {
210
211
            try
212
            {
213 06f13e11 taeseongkim
                var stationList = StationServiceList.Where(x => x.IsOnline);
214
215 0a89a17f taeseongkim
                if (stationList.SelectMany(x => x.ConvertItems).Count(c => c.ProjectNumber == ProjectNo && c.UniqueKey == UniqueKey) == 0)
216 6f6e7dbf taeseongkim
                {
217 06f13e11 taeseongkim
                    var station = stationList.OrderByDescending(x => x.Properties.PROCESS_COUNT - x.AliveCount).FirstOrDefault();
218 6f6e7dbf taeseongkim
219
                    if (station != null)
220
                    {
221 ff4b1e6e taeseongkim
                        System.Diagnostics.Debug.WriteLine($"{station.Properties.SERVICE_ADDRESS}  {station.Properties.PROCESS_COUNT}/{station.AliveCount}");
222
                        var result = await station.Service.ConvertAddAsync(ProjectNo, ConvertID);
223
                        
224
                        if(result.ToLower() == true.ToString().ToLower())
225
                        {
226
                            station.AliveCount++;
227
                        }
228
229 6f6e7dbf taeseongkim
                        logger.Info($"PassConvertItem - Service ID : {station.Properties.ID} ConvertID : {ConvertID}");
230
                    }
231 0157b158 taeseongkim
                }
232
            }
233 6f6e7dbf taeseongkim
            catch (Exception ex)
234
            {
235
                logger.Error($"setDataBaseWaitingList", ex);
236
            }
237 0157b158 taeseongkim
        }
238
239 ff4b1e6e taeseongkim
        /// <summary>
240
        /// 컨버터 프로세스와 AiliveItems을 비교하여 AliveItems에 없는 경우 AliveItems을 제거
241
        /// </summary>
242 06f13e11 taeseongkim
        private void CleanUpAliveQueueItems()
243
        {
244 ff4b1e6e taeseongkim
            if (AliveConvertQueue.Count() > 0)
245 06f13e11 taeseongkim
            {
246 ff4b1e6e taeseongkim
                var processList = Process.GetProcessesByName("Markus.Service.ConvertProcess");
247 06f13e11 taeseongkim
248 ff4b1e6e taeseongkim
                if (processList.Length == 0)
249 06f13e11 taeseongkim
                {
250 ff4b1e6e taeseongkim
                    AliveConvertQueue.Clear();
251
                    System.Diagnostics.Debug.WriteLine("AliveConvertQueue.Clear()");
252
                }
253
                else
254
                {
255
                    var argumentList = processList.Select(f => f.Arguments().CommandLine).SelectMany(f => f);
256
257
                    for (int i = AliveConvertQueue.Count - 1; i >= 0; --i)
258 06f13e11 taeseongkim
                    {
259 ff4b1e6e taeseongkim
                        if (argumentList.Count(x => x == AliveConvertQueue[i].ConvertID) == 0)
260
                        {
261
                            AliveConvertQueue.RemoveAt(i);
262
                        }
263 06f13e11 taeseongkim
                    }
264
                }
265
            }
266
        }
267
268 ff4b1e6e taeseongkim
        /// <summary>
269
        /// 데이터베이스에서 멈춰있거나 
270
        /// </summary>
271
        private async void CleanUpDataBaseItems()
272 0157b158 taeseongkim
        {
273 53c9637d taeseongkim
            using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
274
            {
275 0157b158 taeseongkim
                var items = database.GetConvertingItems(RunProjectList);
276 53c9637d taeseongkim
277 ff4b1e6e taeseongkim
                List< WcfClient.StationServiceTask.ConvertItem> aliveItems = new List<WcfClient.StationServiceTask.ConvertItem>();
278 0157b158 taeseongkim
279 06f13e11 taeseongkim
                foreach (var item in StationServiceList.Where(x=>x.IsOnline))
280 53c9637d taeseongkim
                {
281 0157b158 taeseongkim
                    try
282
                    {
283 ff4b1e6e taeseongkim
                        var serviceItems = await item.Service.AliveConvertListAsync();
284
                        aliveItems.AddRange(serviceItems);
285 0157b158 taeseongkim
                    }
286
                    catch (Exception)
287 53c9637d taeseongkim
                    {
288
                    }
289
                }
290 0157b158 taeseongkim
291
                foreach (var item in items)
292 53c9637d taeseongkim
                {
293 0157b158 taeseongkim
                    if(aliveItems.Count(x=>x.ConvertID == item.ID) == 0)
294
                    {
295
                        database.SetCleanUpItem(item.ID);
296
                    }
297 53c9637d taeseongkim
                }
298
            }
299
        }
300
301 0157b158 taeseongkim
302 53c9637d taeseongkim
        public void Stopprocess()
303
        {
304
            var process = Process.GetProcessesByName("Markus.Service.ConvertProcess");
305
306
            for (int i = process.Count() - 1; i >= 0 ; i--)
307
            {
308
                try
309
                {
310
                    Console.WriteLine($"{i} Process Kill");
311
                    process[i].Kill();
312
                }
313
                catch (Exception ex)
314
                {
315
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
316
                }
317
            }
318
        }
319
320
        /// <summary>
321
        /// finish가 호출되고 살아있는 프로세스라고 추정됨
322
        /// </summary>
323
        public void DeadLockProcessKill()
324
        {
325
            var process = Process.GetProcessesByName("Markus.Service.ConvertProcess");
326
327
            for (int i = process.Count() - 1; i >= 0; i--)
328
            {
329
                try
330
                {
331
                    var commandLines = process[i].Arguments().CommandLine;
332
333
                    if (commandLines.Count() > 0)
334
                    {
335
                        if (ServiceStation.AliveConvertQueue.Count(f => f.ConvertID == commandLines[0]) == 0)
336
                        {
337
                            process[i].Kill();
338
                        }
339
                    }
340
                }
341
                catch (Exception ex)
342
                {
343
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
344
                }
345
            }
346
        }
347
348
        private void ConvertFinish(ConvertItem convertitem)
349
        {
350
            try
351
            {
352
                System.Diagnostics.Debug.WriteLine("Convert Finish : " + convertitem.ConvertID);
353
354
                System.Diagnostics.Debug.WriteLine("ServiceStation.AliveConvertQueue.Count() : " + ServiceStation.AliveConvertQueue.Count());
355
                
356
                ServiceStation.AliveConvertQueue.Remove(convertitem);
357
358
                System.Diagnostics.Debug.WriteLine("ServiceStation.AliveConvertQueue.Count() : " + ServiceStation.AliveConvertQueue.Count());
359
360 06f13e11 taeseongkim
                if (IsStation)
361
                {
362 ff4b1e6e taeseongkim
                    if (!IsReleaseItems)
363
                    {
364
                        System.Diagnostics.Debug.WriteLine("ConvertFinish ReleaseItems call");
365
                        ReleaseItems();
366
                    }
367 06f13e11 taeseongkim
                }
368
                else
369
                {
370
                    if (StationClient != null)
371
                    {
372
                        StationClient.ReleaseConvertItems();
373
                    }
374
                }
375 0157b158 taeseongkim
                //if (ServiceStation.AliveConvertQueue.Count() < MultiProcessCount)
376
                //{
377
                //    setDataBaseWaitingList();
378
                //}
379 53c9637d taeseongkim
            }
380
            catch (Exception ex)
381
            {
382
                logger.Error("ConvertFinish Error",ex);
383
            }
384
        }
385
    }
386
}
클립보드 이미지 추가 (최대 크기: 500 MB)