프로젝트

일반

사용자정보

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

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

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

1
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)