프로젝트

일반

사용자정보

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

markus / ConvertService / ServiceBase / Markus.Service.Station / ServiceStation.cs @ 53f96e00

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