프로젝트

일반

사용자정보

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

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

이력 | 보기 | 이력해설 | 다운로드 (10.3 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
32
        private Uri gServiceHostAddress;
33
34
        private string MarkusDBConnectionString;
35
        private string DownloadTempFolder;
36
        private int MultiThreadMaxPages;
37
        private int MinFontSize;
38 2091a7e5 taeseongkim
        private int UseResolution;
39 53c9637d taeseongkim
        private bool CreateProcessWindow;
40
41
        private int SaveStatusInterval;
42
43
        private List<string> RunProjectList = new List<string>();
44
45
        /// <summary>
46
        /// 프로세스 카운터 자주 람다식을 사용해서 list<int>로 함.
47
        /// </summary>
48
        private List<Int64> ProcessorAffinityList;
49
50
        private string configFileName;
51
52
        public ServiceStation()
53
        {
54
            InitializeComponent();
55
        }
56
57 a53dfe45 taeseongkim
        /// <summary>
58
        /// Config 파일 
59
        /// </summary>
60 53c9637d taeseongkim
        public void GetApplicationConfig()
61
        {
62
            try
63
            {
64
                ConfigParser config = null;
65
66
                try
67
                {
68
                    configFileName = $"{typeof(ServiceStation).Name}.ini";
69
                    config = ConfigHelper.AppConfig(this.configFileName);
70
                }
71
                catch (Exception)
72
                {
73
                    throw new Exception("Config Read Error.");
74
                }
75
76
                if (config != null)
77
                {
78 2091a7e5 taeseongkim
                    MultiProcessCount = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.CONVERT_SERVICE_PROCESS,"5"));
79 53c9637d taeseongkim
80
                    CreateProcessWindow = System.Convert.ToBoolean(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.CREATE_WINDOW, "false"));
81
82
                    // PDF 임시 다운로드 폴더
83 2091a7e5 taeseongkim
                    DownloadTempFolder = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.DOWNLOAD_TEMP_FOLDER,"C:\\temp");
84 53c9637d taeseongkim
85
                    MultiThreadMaxPages = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MULTI_TRHEAD_MAX_PAGE, "500"));
86
87
                    SaveStatusInterval = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.SAVE_STATUS_INTERVAL, "5"));
88
89
                    MinFontSize = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MIN_FONT_SIZE, "10"));
90
91 2091a7e5 taeseongkim
                    UseResolution = System.Convert.ToInt16(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.USE_RESOLUTION, "0"));
92
93 53c9637d taeseongkim
                    // CONVERT DATABASE 연결 문자열
94
                    MarkusDBConnectionString = AESEncrypter.Decrypt(config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.MARKUS_CONNECTION_STRING));
95
96 2091a7e5 taeseongkim
                    var projectList = config.GetValue(CONFIG_DEFINE.SERVICE, CONFIG_DEFINE.FITER_PROCECT,"");
97 53c9637d taeseongkim
98
                    if(!projectList.IsNullOrEmpty())
99
                    {
100
                        RunProjectList = projectList.Split(',').ToList();
101
                    }
102
103
                    // 서비스 ENDPOINT
104
                    // http://localhost/
105
                    var endpointName = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_SERVICE_NAME);
106
                    var port = config.GetValue(CONFIG_DEFINE.WCF_ENDPOINT, CONFIG_DEFINE.STATION_PORT);
107
108
                    if (!string.IsNullOrWhiteSpace(endpointName) && port.IsNumber())
109
                    {
110
                        gServiceHostAddress = UriHelper.UriCreate($"http://localhost:{port}/{endpointName}");
111
                    }
112
                }
113
            }
114
            catch (Exception ex)
115
            {
116
                throw new Exception("ApplicationConfig ", ex);
117
            }
118
        }
119
120
        protected override void OnStart(string[] args)
121
        {
122
            try
123
            {
124
                StartService();
125
            }
126
            catch (Exception ex)
127
            {
128
                logger.Error("ServiceStation Start Error - ", ex);
129
            }
130
        }
131
132
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
133
        {
134
            timer.Stop();
135
136
            var process = Process.GetProcessesByName("Markus.Service.ConvertProcess");
137
138
            for (int i = 0; i < process.Count(); i++)
139
            {
140
                System.Diagnostics.Debug.WriteLine($"Command [{i}]: " , string.Join(" ", process[i].Arguments().CommandLine));
141
            }
142
143
            for (int i = 0; i < ServiceStation.AliveConvertQueue.Count; i++)
144
            {
145
                System.Diagnostics.Debug.WriteLine($"AliveConvertItems  [{i}]: ", ServiceStation.AliveConvertQueue[i].ConvertID);
146
            }
147
148
            System.Threading.Thread.Sleep(1000);
149
            timer.Start();
150
        }
151
152
        System.Timers.Timer timer;
153
154 a53dfe45 taeseongkim
        /// <summary>
155
        /// System.Diagnostics.Process의 ProcessorAffinity Core 선호도를 위한 초기화
156
        /// 설정된 MultiProcessCount에 대해서 프로세스의 코어의 선호도를 지정 한다.
157
        /// 코어의 선택은 비트로 이루어 진다.
158
        /// 8코어에서 1번 코어 00000001
159
        /// 8코어에서 1번 3번 코어 00000101
160
        /// 8코어에서 1번 3번 코어 00000101
161
        /// 8코어에서 1,2,3 선택   00000111
162
        /// https://dotnetgalactics.wordpress.com/2009/10/20/how-to-set-the-processor-affinity-programatically/
163
        /// </summary>
164 53c9637d taeseongkim
        private void ProcessorAffinityInit()
165
        {
166
            ProcessorAffinityList = new List<long>();
167
168
            int processCount = Environment.ProcessorCount;
169
            int AffinityScope = 1;
170
171
            if (processCount > MultiProcessCount)
172
            {
173
                AffinityScope = processCount / MultiProcessCount;
174
            }
175
176
            for (int i = 0; i < processCount - AffinityScope; i += AffinityScope)
177
            {
178
                var bits = new int[processCount];
179
180
                for (int j = i; j < i + AffinityScope; j++)
181
                {
182
                    bits[j] = 1;
183
                }
184
185
                var affinity = System.Convert.ToInt64(string.Join("", bits), 2);
186
187
                ProcessorAffinityList.Add(affinity);
188
            }
189
        }
190
191
        public bool StartService()
192
        {
193
          
194
            try
195
            {
196
                this.GetApplicationConfig();
197
                logger.Info("Read Config");
198
199
                ProcessorAffinityInit();
200
201
            }
202
            catch (Exception e)
203
            {
204
                throw new Exception("Stop StartService Error. ", e);
205
            }
206
            try
207
            {
208 a53dfe45 taeseongkim
                // MarkusPDF.dll에서 pThread lib 사용을 위해 Insatll
209 53c9637d taeseongkim
                if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libpthread.dll")))
210
                {
211
                    Markus.Library.Installer.Install();
212
                    logger.Info("Markus.Library.Installer Install");
213
                }
214
                else
215
                {
216
                    logger.Info("Markus.Library.Installer Exists.");
217
                }
218
                
219
            }
220
            catch (Exception e)
221
            {
222
                throw new Exception("Stop Installer Error. ", e);
223
            }
224
225
            try
226
            {
227 a53dfe45 taeseongkim
                // 기존에 실행 중이던 프로세스 종료
228 53c9637d taeseongkim
                Stopprocess();
229
                logger.Info("Stopprocess");
230
            }
231
            catch (Exception e)
232
            {
233
                throw new Exception("Stop Process Error. ", e);
234
            }
235
236
            try
237
            {
238 a53dfe45 taeseongkim
                // WCF 실행
239 53c9637d taeseongkim
                StartWcfService();
240
241
                if (gWcfServiceHost.BaseAddresses?.Count() > 0)
242
                {
243
                    gServiceHostAddress = gWcfServiceHost.BaseAddresses.First();
244
                }
245
246
                logger.Info($"StartWcfService {gServiceHostAddress}");
247
            }
248
            catch (Exception e)
249
            {
250
                throw new Exception("start Wcf Service Error. ", e);
251
            }
252
253
            try
254
            {
255 a53dfe45 taeseongkim
                // Status가 4이하인 Convert Item을 다시 Convert 함. 
256 53c9637d taeseongkim
                setDataBaseWaitingList();
257
                logger.Info("setDataBaseWaitingList");
258
            }
259
            catch (Exception e)
260
            {
261
                throw new Exception("Database Waiting List Error . ", e);
262
            }
263
264
265
            logger.Info("Start ServiceStation");
266
            //timer = new System.Timers.Timer(10000);
267
            //timer.Elapsed += Timer_Elapsed;
268
            //timer.AutoReset = true;
269
            //timer.Start();
270
271
            return true;
272
        }
273
274
275
        protected override void OnStop()
276
        {
277
            try
278
            {
279
                StopWcfService();
280
                Stopprocess();
281
282
                logger.Info("ServiceStation Stop");
283
            }
284
            catch (Exception e)
285
            {
286
                logger.Error("OnStop Error . ", e);
287
            }
288
        }
289
290
        #region Sleep 방지
291
        //[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
292
        //static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
293
        //[FlagsAttribute]
294
        //public enum EXECUTION_STATE : uint
295
        //{
296
        //    ES_AWAYMODE_REQUIRED = 0x00000040,
297
        //    ES_CONTINUOUS = 0x80000000,
298
        //    ES_DISPLAY_REQUIRED = 0x00000002,
299
        //    ES_SYSTEM_REQUIRED = 0x00000001
300
        //    // Legacy flag, should not be used.
301
        //    // ES_USER_PRESENT = 0x00000004
302
        //}
303
        //public static void PreventScreenAndSleep()
304
        //{
305
        //    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS |
306
        //                            EXECUTION_STATE.ES_SYSTEM_REQUIRED |
307
        //                            EXECUTION_STATE.ES_AWAYMODE_REQUIRED |
308
        //                            EXECUTION_STATE.ES_DISPLAY_REQUIRED);
309
        //} 
310
        #endregion
311
    }
312
}
클립보드 이미지 추가 (최대 크기: 500 MB)