프로젝트

일반

사용자정보

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

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

이력 | 보기 | 이력해설 | 다운로드 (8.23 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
                    ReleaseWorkMemory = 1073741824,
48
                    MultiThreadMaxPages = MultiThreadMaxPages,
49
                    MinFontSize = MinFontSize,
50
                    SendStatusInterval = SaveStatusInterval
51
                };
52
53
                var sendData = ObjectToBytesStringConvert.ObjectToBytesString(processSendData);
54
                
55
                ProcessStartInfo startInfo = new ProcessStartInfo
56
                {
57
                    UseShellExecute = false,
58
                    FileName = "Markus.Service.ConvertProcess.exe",
59
                    WindowStyle = ProcessWindowStyle.Hidden,
60
                    CreateNoWindow = true,
61
                    ErrorDialog = false,
62
                    RedirectStandardError = false,
63
                    Arguments = $"{convertitem.ConvertID.ToString()} {AESEncrypter.Encrypt(sendData)}"
64
                    //Arguments = $"{convertitem.ConvertID.ToString()} {convertitem.ProjectNumber} {AESEncrypter.Encrypt(MarkusDBConnectionString)} {gServiceHostAddress} {DownloadTempFolder} {MultiThreadMaxPages}"
65
                };
66
67
                ConvertProcess.StartInfo = startInfo;
68
                ConvertProcess.EnableRaisingEvents = false;
69
70
                System.Diagnostics.Debug.WriteLine("convert process run : " + startInfo.Arguments);
71
72
73
                if (ConvertProcess.Start())
74
                {
75
                    try
76
                    {
77
                        var processAffinity = ProcessorAffinityList.Except(AliveConvertQueue.Select(f => (long)f.ProcessorAffinity));
78
79
                        if (processAffinity.Count() > 0)
80
                        {
81
                            convertitem.ProcessorAffinity = processAffinity.First();
82
83
                            //int bitMask = 1 << (convertitem.ProcessorAffinity - 1);
84
                            //bitMask |= 1 << (anotherUserSelection - 1); / //  프로세스 두개 이상 선택
85
86
                            ConvertProcess.ProcessorAffinity = new IntPtr(convertitem.ProcessorAffinity);
87
88
                        }
89
                        else
90
                        {
91
                            // 모두 사용중일때 점유율이 작은 걸로 사용
92
                            var CurrentProcessAffinity = AliveConvertQueue.Select(f =>f.ProcessorAffinity).Distinct();
93
94
                            var affinity = CurrentProcessAffinity.Min();
95
96
                            convertitem.ProcessorAffinity = affinity;
97
                            ConvertProcess.ProcessorAffinity = new IntPtr(affinity);
98
                        }
99
                    }
100
                    catch (Exception ex)
101
                    {
102
                        System.Diagnostics.Debug.WriteLine(ex);
103
                    }
104
        
105
106
                    ServiceStation.AliveConvertQueue.Add(convertitem);
107
                    result = true;
108
                }
109
            }
110
            catch (Exception ex)
111
            {
112
                throw new Exception("ConvertThread " + $"{convertitem.ConvertID.ToString()} {convertitem.ProjectNumber} {AESEncrypter.Encrypt(MarkusDBConnectionString)} {gServiceHostAddress} {DownloadTempFolder} {MultiThreadMaxPages}", ex.InnerException);
113
            }
114
            finally
115
            {
116
                //GC.WaitForPendingFinalizers();
117
                //GC.Collect(2);
118
                //GC.Collect(2);
119
            }
120
121
            return result;
122
        }
123
124
        /// <summary>
125
        /// DB에 있는 대기중인 Item을 가져온다.
126
        /// </summary>
127
        public void setDataBaseWaitingList()
128
        {
129
            if (ServiceStation.AliveConvertQueue.Count() == 0)
130
            {
131
                /// 트랜젝션문제로 각각 선언하여 호출한다.
132
                using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
133
                {
134
                    database.SetCleanUpItems(RunProjectList);
135
                }
136
            }
137
138
            using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
139
            {
140
                var _items = database.GetWaitConvertItems(RunProjectList,ServiceStation.AliveConvertQueue, MultiProcessCount - ServiceStation.AliveConvertQueue.Count());
141
142
                if (_items.Count() > 0)
143
                {
144
                    foreach (var item in _items)
145
                    {
146
                        ConvertProcessStart(item);
147
                    }
148
                }
149
                else
150
                {
151
                    System.Diagnostics.Debug.WriteLine("");
152
                }
153
            }
154
        }
155
156
        public void Stopprocess()
157
        {
158
            var process = Process.GetProcessesByName("Markus.Service.ConvertProcess");
159
160
            for (int i = process.Count() - 1; i >= 0 ; i--)
161
            {
162
                try
163
                {
164
                    Console.WriteLine($"{i} Process Kill");
165
                    process[i].Kill();
166
                }
167
                catch (Exception ex)
168
                {
169
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
170
                }
171
            }
172
        }
173
174
        /// <summary>
175
        /// finish가 호출되고 살아있는 프로세스라고 추정됨
176
        /// </summary>
177
        public void DeadLockProcessKill()
178
        {
179
            var process = Process.GetProcessesByName("Markus.Service.ConvertProcess");
180
181
            for (int i = process.Count() - 1; i >= 0; i--)
182
            {
183
                try
184
                {
185
                    var commandLines = process[i].Arguments().CommandLine;
186
187
                    if (commandLines.Count() > 0)
188
                    {
189
                        if (ServiceStation.AliveConvertQueue.Count(f => f.ConvertID == commandLines[0]) == 0)
190
                        {
191
                            process[i].Kill();
192
                        }
193
                    }
194
                }
195
                catch (Exception ex)
196
                {
197
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
198
                }
199
            }
200
        }
201
202
        private void ConvertFinish(ConvertItem convertitem)
203
        {
204
            try
205
            {
206
                System.Diagnostics.Debug.WriteLine("Convert Finish : " + convertitem.ConvertID);
207
208
                System.Diagnostics.Debug.WriteLine("ServiceStation.AliveConvertQueue.Count() : " + ServiceStation.AliveConvertQueue.Count());
209
                
210
                ServiceStation.AliveConvertQueue.Remove(convertitem);
211
212
                System.Diagnostics.Debug.WriteLine("ServiceStation.AliveConvertQueue.Count() : " + ServiceStation.AliveConvertQueue.Count());
213
214
                if (ServiceStation.AliveConvertQueue.Count() < MultiProcessCount)
215
                {
216
                    setDataBaseWaitingList();
217
                }
218
            }
219
            catch (Exception ex)
220
            {
221
                logger.Error("ConvertFinish Error",ex);
222
            }
223
        }
224
    }
225
}
클립보드 이미지 추가 (최대 크기: 500 MB)