Posts

Showing posts from June, 2022

Day 17 : 24 June 2022 : Adding a Configuration File

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #17 : Adding a Configuration File Today we'll add the final component of our configuration design, support for reading a configuration file. There are various standards for configuration file. Which might be another way of saying there is no real standard for configuration files. Here, I've adopted a simple "<name> = <value>" structure. The configuration file settings are given higher precedence than Registry or Environment settings. But they are lower in priority than program arguments. So after we apply system-wide settings values from the Registry (on Windows only) and then apply current Environment (user) settings, then we can apply settings from a configuration file that can be specific to the location where the program is run, so that multiple copies of the program can run concurrently, in different paths, and have distinct settings. Finally, any setting can be overridden with prog...

Day 16 : 23 June 2022 : Applying Windows Registry Settings

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #16 : Applying Windows Registry Settings Today we continue to expand on our application configuration logic. We'll read the Windows registry to apply system-wide setting values. Registry values are applied first. Then, settings are tailored, first from the environment, or user, level and then from program arguments are specific to the execution of the program. Here we've added a general routine to read a setting value from the Registry. Next, we've added the routine that reads all defined Registry settings and applies them to our application class instance. We'll call the new GetRegistryVars method as part of our overall configuration routine. To test, we first add a value in our application's registry space, which was created when we installed Ava as a service. If you don't want to install Ava as a service, you can use the Registry editor to manually create the registry path. We've create...

Day 15 : 22 June 2022 : Add Settings from Environment Variables

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #15 : Adding Settings from Environment Variables So far, we've shown how program arguments can be read and applied to configure Ava settings. Now we'll look at applying setting from Environment variables. This really just makes use of the getenv function in the C library. We'll define setting names and identifiers in our namespace enumerations and const strings. Environment variable settings will be applied before program arguments so that program arguments, which are specific to each execution of the program, can override Environment variables, which are specific to the operating context or user. Here are the environment variable names added in the "driver" namespace. Since the Environment is not specific to the program, we prefix the settings with the program name. Here is a new method in Driver, called GetEnvVars. It simply reads each variable and calls the appropriate method on the singleton...

Day 14 : 21 June 2022 : Running Ava as a Service on Linux

Image
 My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #14 : Running Ava as a Service on Linux Now that we have Ava running as a service on Windows, we can set up Ava to run as a background task, or "daemon", on Linux. We'll add code in Driver to handle the "service" program argument just as we did on Windows. Only for Linux, we'll fork the process, set up handlers to termination signals and close standard streams. Once this code is tested, we can setup Ava to be started automatically by systemd by defining a service configuration file (ava.conf). Installing Ava as a Daemon on Linux The ava.service file is new and defines characteristics of the ava service.  This file is copied into the /lib/systemd/system/ folder. The executable will fork its process on startup. The initial program arguments passed include the "service" parameter. When systemd stops the service, it will issue a simple "kill" command on the main process ID...

Day 13 : 20 June 2022 : Adding Buttons in SwiftUI

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #13 : Adding Buttons in SwiftUI We've made some structural changes in our Ava library. Now we need to revisit our iOS app and catch up with those changes. The Driver class instance in the library is a singleton which is created when the library is loaded. We expose Start and Stop methods on this class to start the Sockets I/O thread and to stop it. Up to now, our iOS app has called Start when the app is launched. But Stop had been called in the Driver destructor. That is no longer the case. So we'll need to call Stop either on-demand or when the app terminates. One advantage of having Start and Stop methods on the Driver is that we should be able to stop the driver and stop it again, repeatedly as needed, without stopping the App entirely. To debug this on iOS, we can replace our message-of-the-day Text control with two Button controls, one to start the driver and one to stop the driver. First, though, we nee...

Day 12 : 19 June 2022 : Adding Windows Service Logic

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #12 : Adding Windows Service Logic Today, we'll add some Win32 API logic in Ava to install, uninstall and run as a service on Windows. We'll add logic in Driver::Service that check if the program was started with the "service" argument as the first program argument. If so, the Service Control Manager will be invoked to start the program as a service. We'll also check for "install" and "uninstall" program arguments and handle these with logic that installs and uninstalls the program, respectively. In a later post, we'll do the equivalent on Linux and macOS and show how to enable Ava to run as a daemon configured in sysctl. Nowadays there are shortcut methods to install and run an executable as a service on Windows. But I prefer to illustrate the APIs that make this work. Some Code Refactoring Up to now we've been using a pointer-to-implementation (pimpl) method for exp...

Day 11: 18 June 2022 : Handling Program Arguments

Image
My 100 Daze of Code https://github.com/davidjwalling/100-days-of-code #11 : Handling Program Arguments Up to now we've been carrying around Ava's program argument count (argc) and value array (argv) into a Configure method. Now it's time to start doing something with those values. We'll define four program settings that can be set by passing program arguments: the logging level, path, prefix and suffix, and show examples of using them. Logging Parameter Storage The singleton theLog is instantiated inside the Ava library (libava). Default values for several logging parameters are set by the Log::Init method, which is called both by the Log class constructor and the destructor, by way of the Reset method, so that runtime values are not left in deallocated storage on operating systems that do not automatically clear memory upon deallocation. Logging Parameter Symbols We use namespaces and enums to define symbolic names for the logging parameters so that we have a single lo...