markus / ConvertService / ServiceBase / Markus.Service.Station / ServiceStation.cs @ 48e1ab34
이력 | 보기 | 이력해설 | 다운로드 (13.5 KB)
1 | 53c9637d | taeseongkim | using log4net; |
---|---|---|---|
2 | using Markus.Service.Extensions; |
||
3 | using Markus.Service.Helper; |
||
4 | using Markus.Service.IWcfService; |
||
5 | using Markus.Service.WcfService; |
||
6 | using Salaros.Configuration; |
||
7 | using System; |
||
8 | using System.Collections.Generic; |
||
9 | using System.ComponentModel; |
||
10 | using System.Data; |
||
11 | using System.Diagnostics; |
||
12 | using System.Globalization; |
||
13 | using System.IO; |
||
14 | using System.Linq; |
||
15 | using System.Runtime.InteropServices; |
||
16 | using System.ServiceModel; |
||
17 | using System.ServiceProcess; |
||
18 | using System.Text; |
||
19 | using System.Threading.Tasks; |
||
20 | using System.Timers; |
||
21 | using static Markus.Service.Extensions.Encrypt; |
||
22 | |||
23 | namespace Markus.Service |
||
24 | { |
||
25 | public partial class ServiceStation : ServiceBase |
||
26 | { |
||
27 | protected ILog logger = LogManager.GetLogger(typeof(ServiceStation)); |
||
28 | protected ServiceHost gWcfServiceHost; |
||
29 | |||
30 | private int MultiProcessCount = 1; |
||
31 | 0157b158 | taeseongkim | private string ServiceID; |
32 | private List<SubStationServiceItem> StationServiceList; |
||
33 | private List<string> StationServiceIDList; |
||
34 | |||
35 | private bool IsWatch; |
||
36 | 53c9637d | taeseongkim | |
37 | private Uri gServiceHostAddress; |
||
38 | |||
39 | private string MarkusDBConnectionString; |
||
40 | private string DownloadTempFolder; |
||
41 | private int MultiThreadMaxPages; |
||
42 | private int MinFontSize; |
||
43 | 2091a7e5 | taeseongkim | private int UseResolution; |
44 | 53c9637d | taeseongkim | private bool CreateProcessWindow; |
45 | 8feb21df | taeseongkim | private long ReleaseWorkMemory; |
46 | 53c9637d | taeseongkim | |
47 | private int SaveStatusInterval; |
||
48 | |||
49 | private List<string> RunProjectList = new List<string>(); |
||
50 | |||
51 | /// <summary> |
||
52 | /// 프로세스 카운터 자주 람다식을 사용해서 list<int>로 함. |
||
53 | /// </summary> |
||
54 | private List<Int64> ProcessorAffinityList; |
||
55 | |||
56 | private string configFileName; |
||
57 | |||
58 | public ServiceStation() |
||
59 | { |
||
60 | InitializeComponent(); |
||
61 | } |
||
62 | |||
63 | a53dfe45 | taeseongkim | /// <summary> |
64 | /// Config 파일 |
||
65 | /// </summary> |
||
66 | 53c9637d | taeseongkim | public void GetApplicationConfig() |
67 | { |
||
68 | try |
||
69 | { |
||
70 | ConfigParser config = null; |
||
71 | |||
72 | try |
||
73 | { |
||
74 | configFileName = $"{typeof(ServiceStation).Name}.ini"; |
||
75 | config = ConfigHelper.AppConfig(this.configFileName); |
||
76 | } |
||
77 | catch (Exception) |
||
78 | { |
||
79 | throw new Exception("Config Read Error."); |
||
80 | } |
||
81 | |||
82 | if (config != null) |
||
83 | { |
||
84 | 0157b158 | taeseongkim | // CONVERT DATABASE 연결 문자열 |
85 | MarkusDBConnectionString = AESEncrypter.Decrypt(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MARKUS_CONNECTION_STRING)); |
||
86 | |||
87 | ServiceID = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SERVICE_ID, Guid.Empty.ToString()); |
||
88 | |||
89 | var servicetList = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SERVICE_LIST, ""); |
||
90 | |||
91 | if (!servicetList.IsNullOrEmpty()) |
||
92 | { |
||
93 | StationServiceIDList = servicetList.Split(',').ToList(); |
||
94 | } |
||
95 | |||
96 | IsWatch = System.Convert.ToBoolean(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.IS_WATCH, "false")); |
||
97 | |||
98 | |||
99 | 2091a7e5 | taeseongkim | MultiProcessCount = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.CONVERT_SERVICE_PROCESS,"5")); |
100 | 53c9637d | taeseongkim | |
101 | CreateProcessWindow = System.Convert.ToBoolean(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.CREATE_WINDOW, "false")); |
||
102 | |||
103 | // PDF 임시 다운로드 폴더 |
||
104 | 2091a7e5 | taeseongkim | DownloadTempFolder = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.DOWNLOAD_TEMP_FOLDER,"C:\\temp"); |
105 | 53c9637d | taeseongkim | |
106 | MultiThreadMaxPages = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MULTI_TRHEAD_MAX_PAGE, "500")); |
||
107 | |||
108 | SaveStatusInterval = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SAVE_STATUS_INTERVAL, "5")); |
||
109 | |||
110 | MinFontSize = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MIN_FONT_SIZE, "10")); |
||
111 | |||
112 | 2091a7e5 | taeseongkim | UseResolution = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.USE_RESOLUTION, "0")); |
113 | |||
114 | 0157b158 | taeseongkim | var workingMemory = System.Convert.ToDouble(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.RELEASE_WORK_MEMORY, "1.5")); |
115 | 8feb21df | taeseongkim | |
116 | ReleaseWorkMemory = MathBytes.Bytes(workingMemory, DataSizeType.GB); |
||
117 | |||
118 | 2091a7e5 | taeseongkim | var projectList = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.FITER_PROCECT,""); |
119 | 53c9637d | taeseongkim | |
120 | if(!projectList.IsNullOrEmpty()) |
||
121 | { |
||
122 | RunProjectList = projectList.Split(',').ToList(); |
||
123 | } |
||
124 | |||
125 | // 서비스 ENDPOINT |
||
126 | // http://localhost/ |
||
127 | var endpointName = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_SERVICE_NAME); |
||
128 | var port = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_PORT); |
||
129 | |||
130 | if (!string.IsNullOrWhiteSpace(endpointName) && port.IsNumber()) |
||
131 | { |
||
132 | gServiceHostAddress = UriHelper.UriCreate($"http://localhost:{port}/{endpointName}"); |
||
133 | } |
||
134 | } |
||
135 | } |
||
136 | catch (Exception ex) |
||
137 | { |
||
138 | throw new Exception("ApplicationConfig ", ex); |
||
139 | } |
||
140 | } |
||
141 | |||
142 | protected override void OnStart(string[] args) |
||
143 | { |
||
144 | try |
||
145 | { |
||
146 | StartService(); |
||
147 | } |
||
148 | catch (Exception ex) |
||
149 | { |
||
150 | logger.Error("ServiceStation Start Error - ", ex); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | private void Timer_Elapsed(object sender, ElapsedEventArgs e) |
||
155 | { |
||
156 | timer.Stop(); |
||
157 | |||
158 | 0157b158 | taeseongkim | //var process = Process.GetProcessesByName("Markus.Service.ConvertProcess"); |
159 | 53c9637d | taeseongkim | |
160 | 0157b158 | taeseongkim | //for (int i = 0; i < process.Count(); i++) |
161 | //{ |
||
162 | // System.Diagnostics.Debug.WriteLine($"Command [{i}]: " , string.Join(" ", process[i].Arguments().CommandLine)); |
||
163 | //} |
||
164 | |||
165 | //for (int i = 0; i < ServiceStation.AliveConvertQueue.Count; i++) |
||
166 | //{ |
||
167 | // System.Diagnostics.Debug.WriteLine($"AliveConvertItems [{i}]: ", ServiceStation.AliveConvertQueue[i].ConvertID); |
||
168 | //} |
||
169 | try |
||
170 | 53c9637d | taeseongkim | { |
171 | 0157b158 | taeseongkim | CleanUpItems(); |
172 | setDataBaseWaitingList(); |
||
173 | 53c9637d | taeseongkim | } |
174 | 0157b158 | taeseongkim | catch (Exception ex) |
175 | 53c9637d | taeseongkim | { |
176 | 0157b158 | taeseongkim | logger.Error("get Wating Item error", ex); |
177 | 53c9637d | taeseongkim | } |
178 | |||
179 | 0157b158 | taeseongkim | System.Threading.Thread.SpinWait(10000); |
180 | 53c9637d | taeseongkim | timer.Start(); |
181 | } |
||
182 | |||
183 | System.Timers.Timer timer; |
||
184 | |||
185 | a53dfe45 | taeseongkim | /// <summary> |
186 | /// System.Diagnostics.Process의 ProcessorAffinity Core 선호도를 위한 초기화 |
||
187 | /// 설정된 MultiProcessCount에 대해서 프로세스의 코어의 선호도를 지정 한다. |
||
188 | /// 코어의 선택은 비트로 이루어 진다. |
||
189 | /// 8코어에서 1번 코어 00000001 |
||
190 | /// 8코어에서 1번 3번 코어 00000101 |
||
191 | /// 8코어에서 1번 3번 코어 00000101 |
||
192 | /// 8코어에서 1,2,3 선택 00000111 |
||
193 | /// https://dotnetgalactics.wordpress.com/2009/10/20/how-to-set-the-processor-affinity-programatically/ |
||
194 | /// </summary> |
||
195 | 53c9637d | taeseongkim | private void ProcessorAffinityInit() |
196 | { |
||
197 | ProcessorAffinityList = new List<long>(); |
||
198 | |||
199 | int processCount = Environment.ProcessorCount; |
||
200 | int AffinityScope = 1; |
||
201 | |||
202 | if (processCount > MultiProcessCount) |
||
203 | { |
||
204 | AffinityScope = processCount / MultiProcessCount; |
||
205 | } |
||
206 | |||
207 | for (int i = 0; i < processCount - AffinityScope; i += AffinityScope) |
||
208 | { |
||
209 | var bits = new int[processCount]; |
||
210 | |||
211 | for (int j = i; j < i + AffinityScope; j++) |
||
212 | { |
||
213 | bits[j] = 1; |
||
214 | } |
||
215 | |||
216 | var affinity = System.Convert.ToInt64(string.Join("", bits), 2); |
||
217 | |||
218 | ProcessorAffinityList.Add(affinity); |
||
219 | } |
||
220 | } |
||
221 | |||
222 | public bool StartService() |
||
223 | { |
||
224 | |||
225 | try |
||
226 | { |
||
227 | this.GetApplicationConfig(); |
||
228 | logger.Info("Read Config"); |
||
229 | |||
230 | ProcessorAffinityInit(); |
||
231 | |||
232 | } |
||
233 | catch (Exception e) |
||
234 | { |
||
235 | throw new Exception("Stop StartService Error. ", e); |
||
236 | } |
||
237 | try |
||
238 | { |
||
239 | a53dfe45 | taeseongkim | // MarkusPDF.dll에서 pThread lib 사용을 위해 Insatll |
240 | 53c9637d | taeseongkim | if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libpthread.dll"))) |
241 | { |
||
242 | Markus.Library.Installer.Install(); |
||
243 | logger.Info("Markus.Library.Installer Install"); |
||
244 | } |
||
245 | else |
||
246 | { |
||
247 | logger.Info("Markus.Library.Installer Exists."); |
||
248 | } |
||
249 | |||
250 | } |
||
251 | catch (Exception e) |
||
252 | { |
||
253 | throw new Exception("Stop Installer Error. ", e); |
||
254 | } |
||
255 | |||
256 | try |
||
257 | { |
||
258 | a53dfe45 | taeseongkim | // 기존에 실행 중이던 프로세스 종료 |
259 | 53c9637d | taeseongkim | Stopprocess(); |
260 | logger.Info("Stopprocess"); |
||
261 | } |
||
262 | catch (Exception e) |
||
263 | { |
||
264 | throw new Exception("Stop Process Error. ", e); |
||
265 | } |
||
266 | |||
267 | try |
||
268 | { |
||
269 | a53dfe45 | taeseongkim | // WCF 실행 |
270 | 53c9637d | taeseongkim | StartWcfService(); |
271 | |||
272 | if (gWcfServiceHost.BaseAddresses?.Count() > 0) |
||
273 | { |
||
274 | gServiceHostAddress = gWcfServiceHost.BaseAddresses.First(); |
||
275 | } |
||
276 | |||
277 | 0157b158 | taeseongkim | // 각 서비스에 컨버터 아이템을 보내기 위한 서비스 초기화 |
278 | if (IsWatch) |
||
279 | { |
||
280 | SetServiceList(this.StationServiceIDList); |
||
281 | } |
||
282 | |||
283 | 53c9637d | taeseongkim | logger.Info($"StartWcfService {gServiceHostAddress}"); |
284 | } |
||
285 | catch (Exception e) |
||
286 | { |
||
287 | throw new Exception("start Wcf Service Error. ", e); |
||
288 | } |
||
289 | |||
290 | 0157b158 | taeseongkim | //try |
291 | //{ |
||
292 | // // Status가 4이하인 Convert Item을 다시 Convert 함. |
||
293 | // setDataBaseWaitingList(); |
||
294 | // logger.Info("setDataBaseWaitingList"); |
||
295 | //} |
||
296 | //catch (Exception e) |
||
297 | //{ |
||
298 | // throw new Exception("Database Waiting List Error . ", e); |
||
299 | //} |
||
300 | 53c9637d | taeseongkim | |
301 | |||
302 | logger.Info("Start ServiceStation"); |
||
303 | 0157b158 | taeseongkim | |
304 | if (IsWatch) |
||
305 | { |
||
306 | logger.Info("ServiceStation Wacth Convert Items"); |
||
307 | |||
308 | timer = new System.Timers.Timer(1000); |
||
309 | timer.Elapsed += Timer_Elapsed; |
||
310 | timer.AutoReset = true; |
||
311 | timer.Start(); |
||
312 | } |
||
313 | 53c9637d | taeseongkim | |
314 | return true; |
||
315 | } |
||
316 | |||
317 | 0157b158 | taeseongkim | public void SetServiceList(List<string> serviceList) |
318 | { |
||
319 | StationServiceList = new List<SubStationServiceItem>(); |
||
320 | |||
321 | using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString)) |
||
322 | { |
||
323 | foreach (var item in serviceList) |
||
324 | { |
||
325 | try |
||
326 | { |
||
327 | var prop = database.GetServiceProperties(item); |
||
328 | |||
329 | if (prop != null) |
||
330 | { |
||
331 | BasicHttpBinding myBinding = new BasicHttpBinding(); |
||
332 | EndpointAddress myEndpoint = new EndpointAddress(UriHelper.UriCreate(prop.SERVICE_ADDRESS)); |
||
333 | var StationServiceClient = new StationService.StationServiceClient(myBinding, myEndpoint); |
||
334 | |||
335 | |||
336 | //var items = StationServiceClient.AliveConvertList(); |
||
337 | |||
338 | StationServiceList.Add(new SubStationServiceItem |
||
339 | { |
||
340 | Properties = prop, |
||
341 | Service = StationServiceClient |
||
342 | }); |
||
343 | } |
||
344 | |||
345 | } |
||
346 | catch (Exception ex) |
||
347 | { |
||
348 | logger.Error($"Service Properties Error ID : { item }"); |
||
349 | } |
||
350 | } |
||
351 | } |
||
352 | } |
||
353 | 53c9637d | taeseongkim | |
354 | protected override void OnStop() |
||
355 | { |
||
356 | try |
||
357 | { |
||
358 | StopWcfService(); |
||
359 | Stopprocess(); |
||
360 | |||
361 | logger.Info("ServiceStation Stop"); |
||
362 | } |
||
363 | catch (Exception e) |
||
364 | { |
||
365 | logger.Error("OnStop Error . ", e); |
||
366 | } |
||
367 | } |
||
368 | |||
369 | #region Sleep 방지 |
||
370 | //[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] |
||
371 | //static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); |
||
372 | //[FlagsAttribute] |
||
373 | //public enum EXECUTION_STATE : uint |
||
374 | //{ |
||
375 | // ES_AWAYMODE_REQUIRED = 0x00000040, |
||
376 | // ES_CONTINUOUS = 0x80000000, |
||
377 | // ES_DISPLAY_REQUIRED = 0x00000002, |
||
378 | // ES_SYSTEM_REQUIRED = 0x00000001 |
||
379 | // // Legacy flag, should not be used. |
||
380 | // // ES_USER_PRESENT = 0x00000004 |
||
381 | //} |
||
382 | //public static void PreventScreenAndSleep() |
||
383 | //{ |
||
384 | // SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | |
||
385 | // EXECUTION_STATE.ES_SYSTEM_REQUIRED | |
||
386 | // EXECUTION_STATE.ES_AWAYMODE_REQUIRED | |
||
387 | // EXECUTION_STATE.ES_DISPLAY_REQUIRED); |
||
388 | //} |
||
389 | #endregion |
||
390 | } |
||
391 | } |