프로젝트

일반

사용자정보

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

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
}
클립보드 이미지 추가 (최대 크기: 500 MB)