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

Savarese Software Research Corporation
Copyright © 2006-2012 Savarese Software Research Corporation. All rights reserved.