Branch data Line data Source code
1 : : /*
2 : : * Copyright 2006-2008 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : /**
18 : : * @file
19 : : * This header defines the service_main utility function template.
20 : : */
21 : :
22 : : #ifndef __SSRC_WISP_UTILITY_SERVICE_MAIN_H
23 : : #define __SSRC_WISP_UTILITY_SERVICE_MAIN_H
24 : :
25 : : #include <ssrc/wisp/service.h>
26 : : #include <ssrc/wisp/utility/ServiceOptions.h>
27 : : #include <ssrc/wisp/utility/ServiceMainOptions.h>
28 : :
29 : : #include <iostream>
30 : :
31 : : __BEGIN_NS_SSRC_WISP_UTILITY
32 : :
33 : : template<typename service_type, typename options_type>
34 : 3 : SSRC_UNIQUE_PTR<service_type> new_service(const options_type & options) {
35 : : return SSRC_UNIQUE_PTR<service_type>(new service_type(options.connection,
36 : : options.name,
37 [ + - ]: 3 : options.capacity));
38 : : }
39 : :
40 : : template<typename service_type, typename options_type, typename init_type>
41 : : SSRC_UNIQUE_PTR<service_type> new_service(const options_type & options,
42 : : const init_type & initializer)
43 : : {
44 : : return SSRC_UNIQUE_PTR<service_type>(new service_type(initializer,
45 : : options.connection,
46 : : options.name,
47 : : options.capacity));
48 : : }
49 : :
50 : : template<typename service_type, typename options_type, bool has_initializer>
51 : : struct ServiceFactory;
52 : :
53 : : template<typename service_type, typename options_type>
54 : : struct ServiceFactory<service_type, options_type, false> {
55 : : typedef SSRC_UNIQUE_PTR<service_type> service_ptr;
56 : 3 : SSRC_UNIQUE_PTR<service_type> operator()(const options_type & options) {
57 : 3 : return new_service<service_type>(options);
58 : : }
59 : : };
60 : :
61 : : template<typename service_type, typename options_type>
62 : : struct ServiceFactory<service_type, options_type, true> {
63 : : typedef SSRC_UNIQUE_PTR<service_type> service_ptr;
64 : : SSRC_UNIQUE_PTR<service_type> operator()(const options_type & options) {
65 : : return new_service<service_type>(options, options.initializer);
66 : : }
67 : : };
68 : :
69 : : struct ServiceMainOptionsProcessor {
70 : : template<typename CustomOptions>
71 : : static int process_options(const CustomOptions & options) {
72 : : if(options.help) {
73 : : std::cout << options.description << std::endl;
74 : : return 0;
75 : : } else if(options.wisp_version) {
76 : : std::cout << "Wisp version: " << WISP_VERSION << std::endl;
77 : : return 0;
78 : : } else if(options.arg_error) {
79 : : std::cerr << "Service option error: " << options.arg_error_msg
80 : : << std::endl;
81 : : return 1;
82 : : }
83 : :
84 : : if(options.connection.empty()) {
85 : : std::cerr << "Service error: You must specify a connection.\n";
86 : : return 1;
87 : : }
88 : :
89 : : if(options.locale.size() > 0)
90 : : std::locale::global(std::locale(std::locale::classic(),
91 : : options.locale.c_str(),
92 : : std::locale::ctype));
93 : : return -1;
94 : : }
95 : : };
96 : :
97 : : template<typename ProtocolProcessor,
98 : : template <typename PP> class EH,
99 : : typename CustomOptions,
100 : : typename CustomOptionsProcessor,
101 : : bool has_initializer>
102 : : int service_main(int argc, char *argv[]) {
103 : : using namespace NS_SSRC_WISP;
104 : : using namespace NS_SSRC_WISP_SERVICE;
105 : : using NS_SSRC_WISP_UTILITY::ServiceOptions;
106 : :
107 : : typedef ServiceOptions<CustomOptions> Options;
108 : : typedef boost::scoped_ptr<Options> options_ptr;
109 : : typedef boost::scoped_ptr<CustomOptionsProcessor> options_processor_ptr;
110 : : typedef Service<EH<ProtocolProcessor> > service_type;
111 : : typedef
112 : : ServiceFactory<service_type, Options, has_initializer> service_factory;
113 : :
114 : : WISP_IMPORT_T(ProtocolProcessor, packing_traits);
115 : :
116 : : string service_name;
117 : :
118 : : try {
119 : : options_processor_ptr options_processor(new CustomOptionsProcessor);
120 : : options_ptr options(new Options(argc, argv));
121 : : int exit_code = options_processor->process_options(*options);
122 : :
123 : : if(exit_code != -1) {
124 : : return exit_code;
125 : : } else {
126 : : service_factory new_service;
127 : : typename service_factory::service_ptr service = new_service(*options);
128 : : EventLoop loop;
129 : : service_name = service->name();
130 : : service->start(loop, options->call_timeout);
131 : : // Free extra memory used by options and options_processor.
132 : : options.reset();
133 : : options_processor.reset();
134 : : loop.start();
135 : : }
136 : : } catch(const NS_SSRC_SPREAD::Error & spread_error) {
137 : : std::cerr << "Service error: " << service_name
138 : : << " : Caught ssrc::spread::Error\n";
139 : : spread_error.print();
140 : : return 1;
141 : : } catch(const std::exception & std_error) {
142 : : std::cerr << "Service error: " << service_name << " : "
143 : : << std_error.what() << std::endl;
144 : : return 1;
145 : : } catch(...) {
146 : : std::cerr << "Service error: " << service_name
147 : : << " : Caught unknown exception!\n";
148 : : throw;
149 : : }
150 : :
151 : : return 0;
152 : : }
153 : :
154 : : #define WISP_EMPTY_INIT_CODE
155 : :
156 : : #define WISP_CUSTOM_SERVICE_MAIN_WITH_INIT(service_type, handler_type, options_type, options_processor_type, has_initializer, init_code) \
157 : : int main(int argc, char *argv[]) { \
158 : : init_code \
159 : : return NS_SSRC_WISP_UTILITY::service_main<service_type, handler_type, options_type, options_processor_type, has_initializer>(argc, argv); \
160 : : }
161 : :
162 : : #define WISP_CUSTOM_SERVICE_MAIN(service_type, handler_type, options_type, options_processor_type, has_initializer) \
163 : : WISP_CUSTOM_SERVICE_MAIN_WITH_INIT(service_type, handler_type, options_type, options_processor_type, has_initializer, WISP_EMPTY_INIT_CODE)
164 : :
165 : : #define WISP_SERVICE_MAIN_WITH_INIT(service_type, init_code) \
166 : : WISP_CUSTOM_SERVICE_MAIN_WITH_INIT(service_type, \
167 : : NS_SSRC_WISP_SERVICE::ServiceEventHandler, \
168 : : NS_SSRC_WISP_UTILITY::ServiceMainOptions, \
169 : : NS_SSRC_WISP_UTILITY::ServiceMainOptionsProcessor, \
170 : : false, init_code)
171 : :
172 : : #define WISP_SERVICE_MAIN(service_type) \
173 : : WISP_SERVICE_MAIN_WITH_INIT(service_type, WISP_EMPTY_INIT_CODE)
174 : :
175 : : __END_NS_SSRC_WISP_UTILITY
176 : :
177 : : #endif
|