Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From qsu-0.0.3 To qsu-0.0.4
2023-11-03
| ||
09:10 | Use Rocket 0.5.0-rc.4. check-in: 074300f463 user: jan tags: qsu-0.0.5, trunk | |
2023-10-29
| ||
14:14 | Fix doc ref. check-in: fb71171304 user: jan tags: qsu-0.0.4, trunk | |
14:11 | Prepare 0.0.4. check-in: b7eb7c0490 user: jan tags: trunk | |
2023-10-25
| ||
14:27 | Remove CbOrigin. Use AppErr for argp errors. check-in: 2190365c01 user: jan tags: trunk | |
2023-10-23
| ||
12:29 | Update index.md. check-in: 0d49c4abb4 user: jan tags: qsu-0.0.3, trunk | |
12:20 | Release maintenance. check-in: ef926ac904 user: jan tags: trunk | |
Changes to Cargo.toml.
1 2 | 1 2 3 4 5 6 7 8 9 10 | - + | [package] name = "qsu" |
︙ | |||
28 29 30 31 32 33 34 | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - + - + | rt = [] tokio = ["rt", "tokio/macros", "tokio/rt-multi-thread", "tokio/signal"] wait-for-debugger = ["dep:dbgtools-win"] [dependencies] async-trait = { version = "0.1.74" } chrono = { version = "0.4.24" } |
︙ |
Changes to examples/argp/mod.rs.
1 2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | - + + + - + + + - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - + + - + - | use clap::ArgMatches; |
Changes to examples/err/mod.rs.
︙ | |||
30 31 32 33 34 35 36 | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | - - + + + + | impl From<qsu::Error> for Error { fn from(err: qsu::Error) -> Self { Error::Qsu(err.to_string()) } } /* |
Changes to examples/hellosvc-rocket.rs.
︙ | |||
92 93 94 95 96 97 98 | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | - + + + + + - + + + - + - - - | // In the future we'll be able to use Try to implement support for implicit // conversion to ProcRes from a Result using `?`, but for now use this hack. ProcRes::into(main2().into()) } fn main2() -> Result<(), Error> { // Derive default service name from executable name. |
︙ |
Changes to examples/hellosvc-tokio.rs.
︙ | |||
86 87 88 89 90 91 92 | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | - + + + + + - + + + - + - - - | // In the future we'll be able to use Try to implement support for implicit // conversion to ProcRes from a Result using `?`, but for now use this hack. ProcRes::into(main2().into()) } fn main2() -> Result<(), Error> { // Derive default service name from executable name. |
Changes to examples/hellosvc.rs.
︙ | |||
89 90 91 92 93 94 95 | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | - + + + + + - + + + - + - - - | // In the future we'll be able to use Try to implement support for implicit // conversion to ProcRes from a Result using `?`, but for now use this hack. ProcRes::into(main2().into()) } fn main2() -> Result<(), Error> { // Derive default service name from executable name. |
Changes to src/argp.rs.
1 2 3 4 5 6 7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | + - + - | //! Helpers for integrating clap into an application using _qsu_. use clap::{builder::Str, Arg, ArgAction, ArgMatches, Args, Command}; use crate::{ err::{AppErr, Error}, installer::{self, RegSvc}, lumberjack::LogLevel, |
︙ | |||
100 101 102 103 104 105 106 | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | - - - - - - - - | .short('n') .long("name") .action(ArgAction::Set) .value_name("SVCNAME") .default_value(Str::from(svcname.to_string())) .help("Set service name"); |
︙ | |||
178 179 180 181 182 183 184 | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | - + - + + + + + + + + - - - + + + + + - - - - - + + + + + - - - + + - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + | let cli = Command::new(cmd.to_string()).arg(namearg); RunSvcArgs::augment_args(cli) } |
︙ | |||
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | + + + + + + + + + + + + + - + | dereg_subcmd: String, run_subcmd: String, cli: Command, cb: &'cb mut dyn ArgsProc } impl<'cb> ArgParser<'cb> { /// Create a new argument parser. /// /// `svcname` is the _default_ service name. It may be overridden using /// command line arguments. pub fn new(svcname: &str, cb: &'cb mut dyn ArgsProc) -> Self { let cli = Command::new(""); Self { svcname: svcname.to_string(), reg_subcmd: "register-service".into(), dereg_subcmd: "deregister-service".into(), run_subcmd: "run-service".into(), cli, cb } } /// Create a new argument parser, basing the root command parser on an /// application-supplied `Command`. /// /// `svcname` is the _default_ service name. It may be overridden using /// command line arguments. pub fn with_cmd( svcname: &str, cli: Command, cb: &'cb mut dyn ArgsProc ) -> Self { Self { svcname: svcname.to_string(), reg_subcmd: "register-service".into(), dereg_subcmd: "deregister-service".into(), run_subcmd: "run-service".into(), cli, cb } } /// Rename the service registration subcommand. pub fn reg_subcmd(mut self, nm: &str) -> Self { self.reg_subcmd = nm.to_string(); self } /// Rename the service deregistration subcommand. pub fn dereg_subcmd(mut self, nm: &str) -> Self { self.dereg_subcmd = nm.to_string(); self } /// Rename the subcommand for running the service. pub fn run_subcmd(mut self, nm: &str) -> Self { self.run_subcmd = nm.to_string(); self } |
︙ | |||
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | + + + + + + + - + + + + + + - + | Ok(ArgpRes::Quit) } Some((subcmd, sub_m)) if subcmd == self.dereg_subcmd => { // Get arguments relating to service deregistration. let args = DeregSvc::from_cmd_match(sub_m); let args = self.cb.proc_rm(sub_m, args)?; installer::uninstall(&args.svcname)?; Ok(ArgpRes::Quit) } Some((subcmd, sub_m)) if subcmd == self.run_subcmd => { // Get arguments relating to running the service. let args = RunSvc::from_cmd_match(sub_m); // Create a RunCtx, mark it as a service, and allow application the // opportunity to modify it based on the parsed command line. let rctx = RunCtx::new(&args.svcname).service(); let rctx = self.cb.proc_run(sub_m, rctx)?; // Return a run context for a background service process. |
︙ | |||
410 411 412 413 414 415 416 | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | + + + + + + + + + + + - + - - - - + + + + + + + + - + - + + + + | /// - If an application-defined subcommand was called, then process it using /// [`ArgsProc::proc_other()`] and then exit. /// - If none of the above subcommands where issued, then run the server /// application as a foreground process. /// /// The `bldr` is a closure that will be called to yield the `SrvAppRt` in /// case the service was requested to run. /// /// # Service registration behavior /// The default service registration behavior in qsu will: /// - Assume that the executable being used to register the service is the /// same one that will run the service. /// - Add the "run service" subcommand to the service's command line /// arguments. /// - If the specified service name is different than the default service /// name (determined by /// [`default_service_name()`](crate::default_service_name), then the /// aguments `--name <service name>` will be added. |
Changes to src/err.rs.
︙ | |||
24 25 26 27 28 29 30 | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | - - - - - - - - - - - - - - + | pub fn run_failed(&self) -> bool { self.run.is_some() } pub fn shutdown_failed(&self) -> bool { self.shutdown.is_some() } |
︙ | |||
83 84 85 86 87 88 89 | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | - + - + - - - + + + - - + + - - - + - - - - | Unsupported } impl Error { pub fn is_apperr(&self) -> bool { |
︙ | |||
143 144 145 146 147 148 149 | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | - + | } impl std::error::Error for Error {} impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { |
︙ | |||
269 270 271 272 273 274 275 276 277 278 279 280 281 282 | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | + + + + + + + + | impl AppErr { pub fn new<E>(e: E) -> Self where E: Send + 'static { Self(Box::new(e)) } /// Inspect error type wrapped by the `AppErr`. pub fn is<T>(&self) -> bool where T: Any { self.0.is::<T>() } /// Attempt to unpack and cast the inner error type. /// /// If it can't be downcast to `E`, `AppErr` will be returned in the `Err()` /// case. /// /// ``` |
︙ | |||
320 321 322 323 324 325 326 | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | - + - - - - + - - - + + - - - + - - - | let Ok(e) = self.0.downcast::<E>() else { panic!("Unable to downcast to error type E"); }; *e } } |
Changes to src/installer/winsvc.rs.
︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | + + + + + | err::Error, rt::winsvc::{ create_service_params, get_service_params_subkey, write_service_subkey } }; /// Register a service in the system service's subsystem. // ToDo: Make notes about Windows-specific semantics: // - Uses registry // - Installer // - Windows Event Log pub fn install(ctx: super::RegSvc) -> Result<(), Error> { let svcname = &ctx.svcname; // Create a refrence cell used to keep track of whether to keep system // motifications (or not) when leaving function. let status = RefCell::new(false); |
︙ |
Changes to src/lib.rs.
︙ | |||
52 53 54 55 56 57 58 | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | - + | use std::{ffi::OsStr, path::Path}; pub use async_trait::async_trait; pub use lumberjack::LumberJack; |
︙ |
Changes to src/rt.rs.
︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | + + + + | /// Mark this run context to run under the operating system's subservice, if /// one is available on this platform. pub fn service_ref(&mut self) -> &mut Self { self.service = true; self } pub fn is_service(&self) -> bool { self.service } /// Launch the application. /// /// If this `RunCtx` has been marked as a _service_ then it will perform the /// appropriate service subsystem integration before running the actual /// server application code. /// |
︙ |
Changes to www/changelog.md.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | + + + + + + + + + + + + + + + + + + + | # Change log ## [Unreleased] ### Added ### Changed ### Removed --- ## [0.0.4] - 2023-10-29 ### Added - Add the remaining `ArgsProc` callbacks in `ArgParser`. ### Changed - Rather than pass a creation closure to the `ArgParser::proc()` for the run case, add a `ArgsProc::build_apprt()` that'll be invoked to create the runtime instead. - More consistently use `AppErr` for callbacks. ### Removed - Removed `err::CbOrigin`. --- ## [0.0.3] - 2023-10-23 ### Added - Introduce an `AppErr` type that can wrap application-specific errors that |
︙ |
Changes to www/index.md.
︙ | |||
86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | + + + + + + + + | _qsu_ is negligible (or it might even be wasteful to pull in _qsu_). The benefits of using _qsu_ will be noticed mostly when targeting the Windows Services subsystem. But mostly the benefits become apparent when targetting multiple service subsystems in the same project, and wanting to have a similar API when developing non-async and async services. ## General tips - The logging/tracing facilities aren't initialized until the server application's runtime has been initialized, because the runtime type may affect the logging/tracing backends. As an implication of this, services that use the `ArgParser` should defer operations that need logging/tracking until the service handler's `init()` trait method is called. ## Feature labels in documentation The crate's documentation uses automatically generated feature labels, which currently requires nightly featuers. To build the documentation locally use: ``` RUSTFLAGS="--cfg docsrs" RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features |
︙ | |||
126 127 128 129 130 131 132 | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | - - - + + + + + + | The details of changes can always be found in the timeline, but for a high-level view of changes between released versions there's a manually maintained [Change Log](./changelog.md). ## Project status |