프로젝트

일반

사용자정보

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

markus / ConvertService / ServiceBase / Markus.Service.Station / ServiceStation.cs @ a8f1a865

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

1 53c9637d taeseongkim
using log4net;
2 60723dc9 taeseongkim
using Markus.EntityModel;
3 53c9637d taeseongkim
using Markus.Service.Extensions;
4
using Markus.Service.Helper;
5
using Markus.Service.IWcfService;
6
using Markus.Service.WcfService;
7
using Salaros.Configuration;
8
using System;
9
using System.Collections.Generic;
10
using System.ComponentModel;
11
using System.Data;
12
using System.Diagnostics;
13
using System.Globalization;
14
using System.IO;
15
using System.Linq;
16
using System.Runtime.InteropServices;
17
using System.ServiceModel;
18 1ae729e4 taeseongkim
using System.ServiceModel.Channels;
19
using System.ServiceModel.Dispatcher;
20 53c9637d taeseongkim
using System.ServiceProcess;
21
using System.Text;
22
using System.Threading.Tasks;
23
using System.Timers;
24
using static Markus.Service.Extensions.Encrypt;
25
26
namespace Markus.Service
27
{
28
    public partial class ServiceStation : ServiceBase
29
    {
30
        protected ILog logger = LogManager.GetLogger(typeof(ServiceStation));
31
        protected ServiceHost gWcfServiceHost;
32 60723dc9 taeseongkim
        private SERVICE_PROPERTIES ServiceProperty;
33 53c9637d taeseongkim
34 ff4b1e6e taeseongkim
        private static System.Timers.Timer timer;
35 06f13e11 taeseongkim
        
36 0157b158 taeseongkim
        private string ServiceID;
37
        private List<SubStationServiceItem> StationServiceList;
38
        private List<string> StationServiceIDList;
39 60723dc9 taeseongkim
        private Service.WcfClient.StationServiceTask.StationServiceClient StationClient;
40 06f13e11 taeseongkim
        private bool IsStation;
41 53c9637d taeseongkim
42
        private Uri gServiceHostAddress;
43
44
        private string MarkusDBConnectionString;
45
        private string DownloadTempFolder;
46
        private int MultiThreadMaxPages;
47
        private int MinFontSize;
48 2091a7e5 taeseongkim
        private int UseResolution;
49 53c9637d taeseongkim
        private bool CreateProcessWindow;
50 8feb21df taeseongkim
        private long ReleaseWorkMemory;
51 53c9637d taeseongkim
52
        private int SaveStatusInterval;
53
54 06f13e11 taeseongkim
        private static bool IsReleaseItems;
55
56 53c9637d taeseongkim
        private List<string> RunProjectList = new List<string>();
57
58
        /// <summary>
59
        /// 프로세스 카운터 자주 람다식을 사용해서 list<int>로 함.
60
        /// </summary>
61
        private List<Int64> ProcessorAffinityList;
62
63
        private string configFileName;
64
65
        public ServiceStation()
66
        {
67
            InitializeComponent();
68
        }
69
70 a53dfe45 taeseongkim
        /// <summary>
71
        /// Config 파일 
72
        /// </summary>
73 53c9637d taeseongkim
        public void GetApplicationConfig()
74
        {
75
            try
76
            {
77
                ConfigParser config = null;
78
79
                try
80
                {
81
                    configFileName = $"{typeof(ServiceStation).Name}.ini";
82
                    config = ConfigHelper.AppConfig(this.configFileName);
83
                }
84
                catch (Exception)
85
                {
86
                    throw new Exception("Config Read Error.");
87
                }
88
89
                if (config != null)
90
                {
91 0157b158 taeseongkim
                    // CONVERT DATABASE 연결 문자열
92
                    MarkusDBConnectionString = AESEncrypter.Decrypt(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MARKUS_CONNECTION_STRING));
93
94 06f13e11 taeseongkim
                    IsStation = System.Convert.ToBoolean(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.IS_STATAION, "false"));
95 0157b158 taeseongkim
96 06f13e11 taeseongkim
                    ServiceID = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SERVICE_ID, Guid.Empty.ToString());
97 0157b158 taeseongkim
98 06f13e11 taeseongkim
                    if (IsStation)
99 0157b158 taeseongkim
                    {
100 06f13e11 taeseongkim
                        var servicetList = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SERVICE_LIST, "");
101 0157b158 taeseongkim
102 06f13e11 taeseongkim
                        if (!servicetList.IsNullOrEmpty())
103
                        {
104
                            StationServiceIDList = servicetList.Split(',').ToList();
105
                        }
106
                    }
107
                    else
108
                    {
109
                        var address = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.STATAION_ADDRESS,"");
110 0157b158 taeseongkim
111 06f13e11 taeseongkim
                        if (!address.IsNullOrEmpty())
112
                        {
113
                            BasicHttpBinding myBinding = new BasicHttpBinding();
114
                            EndpointAddress myEndpoint = new EndpointAddress(UriHelper.UriCreate(address));
115 60723dc9 taeseongkim
                            StationClient = new WcfClient.StationServiceTask.StationServiceClient(myBinding, myEndpoint);
116 06f13e11 taeseongkim
                        }
117
                    }
118 53c9637d taeseongkim
119
                    CreateProcessWindow = System.Convert.ToBoolean(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.CREATE_WINDOW, "false"));
120
121
                    // PDF 임시 다운로드 폴더
122 2091a7e5 taeseongkim
                    DownloadTempFolder = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.DOWNLOAD_TEMP_FOLDER,"C:\\temp");
123 53c9637d taeseongkim
124
                    MultiThreadMaxPages = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MULTI_TRHEAD_MAX_PAGE, "500"));
125
126
                    SaveStatusInterval = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SAVE_STATUS_INTERVAL, "5"));
127
128
                    MinFontSize = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MIN_FONT_SIZE, "10"));
129
130 2091a7e5 taeseongkim
                    UseResolution = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.USE_RESOLUTION, "0"));
131
132 0157b158 taeseongkim
                    var workingMemory = System.Convert.ToDouble(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.RELEASE_WORK_MEMORY, "1.5"));
133 8feb21df taeseongkim
134
                    ReleaseWorkMemory = MathBytes.Bytes(workingMemory, DataSizeType.GB);
135
136 2091a7e5 taeseongkim
                    var projectList = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.FITER_PROCECT,"");
137 53c9637d taeseongkim
138
                    if(!projectList.IsNullOrEmpty())
139
                    {
140
                        RunProjectList = projectList.Split(',').ToList();
141
                    }
142
143
                    // 서비스 ENDPOINT
144
                    // http://localhost/
145
                    var endpointName = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_SERVICE_NAME);
146
                    var port = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_PORT);
147
148
                    if (!string.IsNullOrWhiteSpace(endpointName) && port.IsNumber())
149
                    {
150
                        gServiceHostAddress = UriHelper.UriCreate($"http://localhost:{port}/{endpointName}");
151
                    }
152 60723dc9 taeseongkim
153
                    using (Markus.Service.DataBase.ConvertDatabase db = new Markus.Service.DataBase.ConvertDatabase(MarkusDBConnectionString))
154
                    {
155
                        ServiceProperty = db.GetServiceProperties(ServiceID);
156
                    }
157 53c9637d taeseongkim
                }
158
            }
159
            catch (Exception ex)
160
            {
161
                throw new Exception("ApplicationConfig ", ex);
162
            }
163
        }
164
165
        protected override void OnStart(string[] args)
166
        {
167
            try
168
            {
169
                StartService();
170
            }
171
            catch (Exception ex)
172
            {
173
                logger.Error("ServiceStation Start Error - ", ex);
174
            }
175
        }
176
177
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
178
        {
179 ff4b1e6e taeseongkim
     
180 1ae729e4 taeseongkim
            //System.Diagnostics.Debug.WriteLine("timer : " + e?.SignalTime);
181
            //try
182
            //{
183
            //    if (!IsReleaseItems)
184
            //    {
185
            //        ReleaseItems();
186
            //    }
187
188
            //    if ((DateTime.Now - logTime) >= new TimeSpan(0, 5, 0))
189
            //    {
190
            //        logTime = DateTime.Now;
191
            //        logger.Info("StationService Alive Check");
192
            //    }
193
            //}
194
            //catch (Exception ex)
195
            //{
196
            //    logger.Error("Timer Error " ,ex);
197
            //}
198 ff4b1e6e taeseongkim
199 1ae729e4 taeseongkim
            //System.Threading.Thread.SpinWait(1000);
200 0157b158 taeseongkim
201 1ae729e4 taeseongkim
            //timer.Start();
202 06f13e11 taeseongkim
        }
203
204
        /// <summary>
205
        /// alivequeue와 process를 비교하여 정리하고
206
        /// 대기중인 아이템을 분배한다.
207
        /// </summary>
208
        private void ReleaseItems()
209
        {
210 0157b158 taeseongkim
            try
211 53c9637d taeseongkim
            {
212 06f13e11 taeseongkim
                IsReleaseItems = true;
213
214
                CleanUpAliveQueueItems();
215
216
                if (IsStation)
217
                {
218 60723dc9 taeseongkim
                    //if (IsDataBaseWaitingList(1))
219
                    //{
220 1ae729e4 taeseongkim
                    System.Diagnostics.Debug.WriteLine("ReleaseItems start");
221
                    ReflashSubServiceAsync();
222
223
                    if (StationServiceList.All(x => x.IsOnline))
224
                    {
225 ff4b1e6e taeseongkim
                        CleanUpDataBaseItems();
226
                        setDataBaseWaitingList();
227 1ae729e4 taeseongkim
                    }
228
                    else
229
                    {
230
                        System.Diagnostics.Debug.WriteLine("Service Any Offline");
231
                    }
232
233
                    System.Diagnostics.Debug.WriteLine("ReleaseItems end");
234 60723dc9 taeseongkim
                    //}
235 06f13e11 taeseongkim
                }
236 53c9637d taeseongkim
            }
237 0157b158 taeseongkim
            catch (Exception ex)
238 53c9637d taeseongkim
            {
239 0157b158 taeseongkim
                logger.Error("get Wating Item error", ex);
240 53c9637d taeseongkim
            }
241
242 06f13e11 taeseongkim
            IsReleaseItems = false;
243 53c9637d taeseongkim
        }
244
245 a53dfe45 taeseongkim
        /// <summary>
246
        /// System.Diagnostics.Process의 ProcessorAffinity Core 선호도를 위한 초기화
247
        /// 설정된 MultiProcessCount에 대해서 프로세스의 코어의 선호도를 지정 한다.
248
        /// 코어의 선택은 비트로 이루어 진다.
249
        /// 8코어에서 1번 코어 00000001
250
        /// 8코어에서 1번 3번 코어 00000101
251
        /// 8코어에서 1번 3번 코어 00000101
252
        /// 8코어에서 1,2,3 선택   00000111
253
        /// https://dotnetgalactics.wordpress.com/2009/10/20/how-to-set-the-processor-affinity-programatically/
254
        /// </summary>
255 53c9637d taeseongkim
        private void ProcessorAffinityInit()
256
        {
257
            ProcessorAffinityList = new List<long>();
258
259
            int processCount = Environment.ProcessorCount;
260
            int AffinityScope = 1;
261
262 60723dc9 taeseongkim
            if (processCount > ServiceProperty.PROCESS_COUNT)
263 53c9637d taeseongkim
            {
264 60723dc9 taeseongkim
                AffinityScope = processCount / ServiceProperty.PROCESS_COUNT;
265 53c9637d taeseongkim
            }
266
267
            for (int i = 0; i < processCount - AffinityScope; i += AffinityScope)
268
            {
269
                var bits = new int[processCount];
270
271
                for (int j = i; j < i + AffinityScope; j++)
272
                {
273
                    bits[j] = 1;
274
                }
275
276
                var affinity = System.Convert.ToInt64(string.Join("", bits), 2);
277
278
                ProcessorAffinityList.Add(affinity);
279
            }
280
        }
281
282
        public bool StartService()
283
        {
284
          
285
            try
286
            {
287
                this.GetApplicationConfig();
288
                logger.Info("Read Config");
289
290 60723dc9 taeseongkim
                if (ServiceProperty != null)
291
                {
292
                    ProcessorAffinityInit();
293
                }
294
                else
295
                {
296
                    throw new Exception("StartService Error. ServiceProperty is Null");
297
                }
298 53c9637d taeseongkim
299
            }
300
            catch (Exception e)
301
            {
302 60723dc9 taeseongkim
                throw new Exception("StartService Error. ", e);
303 53c9637d taeseongkim
            }
304 60723dc9 taeseongkim
305 53c9637d taeseongkim
            try
306
            {
307 a53dfe45 taeseongkim
                // MarkusPDF.dll에서 pThread lib 사용을 위해 Insatll
308 53c9637d taeseongkim
                if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libpthread.dll")))
309
                {
310
                    Markus.Library.Installer.Install();
311
                    logger.Info("Markus.Library.Installer Install");
312
                }
313
                else
314
                {
315
                    logger.Info("Markus.Library.Installer Exists.");
316
                }
317
                
318
            }
319
            catch (Exception e)
320
            {
321
                throw new Exception("Stop Installer Error. ", e);
322
            }
323
324
            try
325
            {
326 a53dfe45 taeseongkim
                // 기존에 실행 중이던 프로세스 종료
327 53c9637d taeseongkim
                Stopprocess();
328
                logger.Info("Stopprocess");
329
            }
330
            catch (Exception e)
331
            {
332
                throw new Exception("Stop Process Error. ", e);
333
            }
334
335
            try
336
            {
337 a53dfe45 taeseongkim
                // WCF 실행
338 53c9637d taeseongkim
                StartWcfService();
339
340
                if (gWcfServiceHost.BaseAddresses?.Count() > 0)
341
                {
342
                    gServiceHostAddress = gWcfServiceHost.BaseAddresses.First();
343
                }
344
345 0157b158 taeseongkim
                //  각 서비스에 컨버터 아이템을 보내기 위한 서비스 초기화
346 06f13e11 taeseongkim
                if (IsStation)
347 0157b158 taeseongkim
                {
348
                    SetServiceList(this.StationServiceIDList);
349
                }
350
351 53c9637d taeseongkim
                logger.Info($"StartWcfService {gServiceHostAddress}");
352
            }
353
            catch (Exception e)
354
            {
355
                throw new Exception("start Wcf Service Error. ", e);
356
            }
357
358 0157b158 taeseongkim
            //try
359
            //{
360
            //    // Status가 4이하인 Convert Item을 다시 Convert 함. 
361
            //    setDataBaseWaitingList();
362
            //    logger.Info("setDataBaseWaitingList");
363
            //}
364
            //catch (Exception e)
365
            //{
366
            //    throw new Exception("Database Waiting List Error . ", e);
367
            //}
368 53c9637d taeseongkim
369
370
            logger.Info("Start ServiceStation");
371 60723dc9 taeseongkim
            var autoEvent = new System.Threading.AutoResetEvent(false);
372
373 1ae729e4 taeseongkim
            stateTimer = new System.Threading.Timer(new System.Threading.TimerCallback(TimerCallBack), null, 0, 500);
374 60723dc9 taeseongkim
            //timer = new System.Timers.Timer(new TimeSpan(0, 0, 0, 10).TotalMilliseconds);
375
            //timer.Elapsed += Timer_Elapsed;
376
            //timer.AutoReset = true;
377
            //timer.Start();
378
            //Timer_Elapsed(null, null);
379 53c9637d taeseongkim
            return true;
380
        }
381
382 60723dc9 taeseongkim
        System.Threading.Timer stateTimer;
383
        DateTime logTime;
384 1ae729e4 taeseongkim
        DateTime ReleaseTime;
385 60723dc9 taeseongkim
386
        private void TimerCallBack(object state)
387
        {
388
            System.Threading.AutoResetEvent autoEvent = (System.Threading.AutoResetEvent)state;
389
            //stateTimer.Change(-1, -1);
390
            try
391
            {
392 1ae729e4 taeseongkim
               
393
                if ((DateTime.Now - ReleaseTime) >= new TimeSpan(0, 0,15))
394 60723dc9 taeseongkim
                {
395 1ae729e4 taeseongkim
                    if (!IsReleaseItems)
396
                    {
397
                        ReleaseItems();
398
                    }
399
                    ReleaseTime = DateTime.Now;
400 60723dc9 taeseongkim
                }
401 1ae729e4 taeseongkim
              
402 60723dc9 taeseongkim
403
                if ((DateTime.Now - logTime) >= new TimeSpan(0, 5, 0))
404
                {
405
                    logTime = DateTime.Now;
406
                    logger.Info("StationService Alive Check");
407
                }
408
409 1ae729e4 taeseongkim
410 60723dc9 taeseongkim
            }
411
            catch (Exception ex)
412
            {
413
                logger.Error("Timer Error ", ex);
414
            }
415 1ae729e4 taeseongkim
416
            ///System.Threading.Thread.SpinWait(100000);
417
            //stateTimer.Change(0, 10000);
418 60723dc9 taeseongkim
        }
419
420 0157b158 taeseongkim
        public void SetServiceList(List<string> serviceList)
421
        {
422
            StationServiceList = new List<SubStationServiceItem>();
423
424
            using (DataBase.ConvertDatabase database = new DataBase.ConvertDatabase(MarkusDBConnectionString))
425
            {
426
                foreach (var item in serviceList)
427
                {
428
                    try
429
                    {
430
                        var prop = database.GetServiceProperties(item);
431
432
                        if (prop != null)
433
                        {
434 1ae729e4 taeseongkim
                            BasicHttpBinding httpbinding = new BasicHttpBinding();
435
                            httpbinding.CloseTimeout = new TimeSpan(0, 10, 0);
436
                            httpbinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
437
                            httpbinding.SendTimeout = new TimeSpan(0, 10, 0);
438
                            httpbinding.OpenTimeout = new TimeSpan(0, 10, 0);
439
440 0157b158 taeseongkim
                            EndpointAddress myEndpoint = new EndpointAddress(UriHelper.UriCreate(prop.SERVICE_ADDRESS));
441 1ae729e4 taeseongkim
                            var StationServiceClient = new WcfClient.StationServiceTask.StationServiceClient(httpbinding, myEndpoint);
442 0157b158 taeseongkim
                        
443
                       
444
                                //var items = StationServiceClient.AliveConvertList();
445
                            
446
                                StationServiceList.Add(new SubStationServiceItem
447
                                {
448
                                    Properties = prop,
449
                                    Service = StationServiceClient
450
                                });
451
                        }
452
453
                    }
454
                    catch (Exception ex)
455
                    {
456 06f13e11 taeseongkim
                        logger.Error($"Service Properties Error  ID : { item }",ex);
457 0157b158 taeseongkim
                    }
458
                }
459
            }
460
        }
461 53c9637d taeseongkim
462
        protected override void OnStop()
463
        {
464
            try
465
            {
466 1ae729e4 taeseongkim
                if (timer != null)
467
                {
468
                    timer.Stop();
469
                }
470
471 53c9637d taeseongkim
                StopWcfService();
472
                Stopprocess();
473
474
                logger.Info("ServiceStation Stop");
475
            }
476
            catch (Exception e)
477
            {
478
                logger.Error("OnStop Error . ", e);
479
            }
480
        }
481
482
        #region Sleep 방지
483
        //[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
484
        //static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
485
        //[FlagsAttribute]
486
        //public enum EXECUTION_STATE : uint
487
        //{
488
        //    ES_AWAYMODE_REQUIRED = 0x00000040,
489
        //    ES_CONTINUOUS = 0x80000000,
490
        //    ES_DISPLAY_REQUIRED = 0x00000002,
491
        //    ES_SYSTEM_REQUIRED = 0x00000001
492
        //    // Legacy flag, should not be used.
493
        //    // ES_USER_PRESENT = 0x00000004
494
        //}
495
        //public static void PreventScreenAndSleep()
496
        //{
497
        //    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS |
498
        //                            EXECUTION_STATE.ES_SYSTEM_REQUIRED |
499
        //                            EXECUTION_STATE.ES_AWAYMODE_REQUIRED |
500
        //                            EXECUTION_STATE.ES_DISPLAY_REQUIRED);
501
        //} 
502
        #endregion
503
    }
504
}
클립보드 이미지 추가 (최대 크기: 500 MB)