A step towards more ecological software development

Have you ever wondered if you, as a software developer, can do more to reduce your carbon footprint? What about the carbon footprint of all the apps you’ve deployed? 

Generally, in software development, you don’t hear a lot about this topic. But why is that? Can we not make enough impact? Is it even worth putting some effort in? 

Changing mindset

There are a lot of aspects in which software can be made more efficient, in order to reduce the computing power needed. Database queries can be made more performant, extra roundtrips can be avoided, unnecessary data doesn’t have to be stored, redundant calculations may be removed, log retention and the amount of logs could be reduced, multiple application instances running simultaneously could potentially be scaled down,… You name it. But do we actually care enough? Usually, when we think of improving these things, we usually do it to improve user experience, but rarely do we think about the ecological impact. We can actually change that. Let’s be a little more conscious in how we technically design our applications. The more of us who think about it, the more significant the overall impact can become over our shared application landscapes.

 

The trigger

To be honest with you, I didn’t always kept the ecological point of view in mind while developing applications. Sure, I thought about performance and log retention, caching were it would be advantageous, reducing round trips, introducing indexes in database queries, but I didn necessarily have the ecological footprint of the application in mind. But then I came accross an interesting post on LinkedIn, that changed this:

This immediately triggered me, and I went on to watch the Devoxx presentation on YouTube, which I truly recommend watching:

Green scheduling

Let’s talk a bit more about the software in the conference talk.

What is it? In a nutshell, it is software that allows you to schedule recurring tasks, like nightly jobs, considering the carbon intensity at the planned execution time. The aim is to run the task at the most opportune moment, being the window of time where carbon intensity would be at its lowest point.

Currently, the software consists of a propriatry API (maintained by First8) as well as an open source Java library. There are plans to support more programming languages in the future. Currently there is already support for the Spring and Quarkus frameworks.

The API is in charge of calculating the most desirable window in which to execute a given job, for a given time zone and region. It also takes an expected duration amount into consideration. Currently, the API is free of charge, but you do require an API key. You can easily set it up though, do go through the steps as documented on their Get Started page.

The library provides the annotation, its processing and the logic calling the API and the scheduled job management.

You are most likely already familiar with Spring’s Scheduled annotation, where you would define recurring jobs like so for example:
@Scheduled(cron = "0 0 2 * * ?", zone = "Europe/Brussels"). Using the library’s equivalent annotation, you would define that like so:
@GreenScheduled(fixedWindow = "02:00 08:00", carbonIntensityZone = "BE", duration = "1h" timeZone= "Europe/Brussels").
Note that instead of always running the job at 2AM, now we specify a time window. The carbonIntensityZone maps to a region as defined with ENTSO-E, from which the API consumes data. You also see that we need to pass a duration parameter, this is mandatory at the moment, and can be a rough estimation of the time the batch job would need to complete. Perhaps, this will be made a bit smarter in the future.

An example I’m personally already using in a hobby project:

@GreenScheduled(
fixedWindow = "01:00 23:00",
duration = "1h",
carbonIntensityZone = "BE",
timeZone = "Europe/Brussels",
dayOfWeek = "MON"
)
public void cleanUpArchivedLogs() {
// Log cleanup code omitted
}

As you can see, there’s different options for defining when the job has to run.
Of course, you would have to use this mindfully. If the job you want to execute is required to run at a specific time (do ask the question: why?), this approach doesn’t fit your case. But for jobs, like the above, where the execution time is not that important, go for it!

Now, imagine the impact it would make if all of us would consider something like this when setting up scheduled jobs. Every job can literally contribute in reducing the carbon footprint.

Even considering the downside of the extra API call and the computing power required for it to come up with the most suitable execution time, we will usually save more carbon, given we setup wide enough windows.

However, the supported regions, at the time of writing, only include ‘NL’. First8 (a Dutch company) does however plan to support a lot more regions, but the timeline on that is not yet very clear. If you are interested in support for a given region, do contact them to request support for it.  

Do not hesitate to contribute to the project on GitHub. The team is welcoming any change or improvement and they setup very easy-to-follow setup and contribution guidelines.

I’m playing around with the software myself. I’m evaluating wether it is ready for use in production applications (mostly region support seems to be lacking).
I’ve also contributed 2 minor changes to the library to show my support:
Implement Autocloseable on schedulers
Javadoc improvements

Green energy production often relies on multiple weather factors like, sun, wind, rain (for hydro plants),… And this little piece of software tries to make better use of that.

Moving forward

The green-scheduler I’ve just ellaborated on is of course not the only answer to improving our shared carbon footprint. It is a good step in the right direction. It makes us reflect on what we can do better. And that’s exactly it, that’s exactly what we need to start doing a little bit more.

Do you have suggestions to further improve ourselves on the topic? Or are there already other things you are actively doing to make an impact? Do let me know in a comment, I would be very interested in hearing about it, or to start a conversation!

Managing Application Properties in Spring Boot

Many projects deal with application-wide parameters, mostly called properties. These are inputs to the program, that wouldn’t normally be changed. They do however provide for simple setup in multiple circumstances.

When to Use Properties

Good example situations in which properties would come in handy are database and email setups. If your application sends out mails, it will need to set some parameters, like protocol, host and port. If authentication is involved, properties should cover them as well. In your emailing implementation you would then read out the property values and handle them however required.

Mail properties
Some application properties for outgoing email for local development.

There are many advantages of setting these parameters in one centralized file. One of which is that quick adjustments can easily be made, without touching the code (that is, when only values are edited). When an application is deployed on multiple environments (local development, acceptance, staging, production,…) it would be enough to adjust properties in accordance with the environment on which the app is running on.

 

Reading Properties in Spring

When it comes down to extracting the values from the property file(s) when using Spring, you have a few options.

The first option, which is also the quickest solution, is to use the @Value annotation on class members or directly in an autowired constructor, as a parameters.

@Value("${my.property.name}")
private String myProperty;
@Autowired
 public MyConstructor(@Value("${my.property.name}") final String property) {
     this.property = property;
 }

Just pass your property key to the annotation. That’s it, no need to use any file reader, Spring deals with that for you. However this method is very quick and easy to implement, I’d like to point out that whenever you decide to edit the property key, you would also have to adjust it in the annotation value in code. And that would be for every annotation that reads out the edited property in question. This could obviously be made a bit more efficient and future proof.

Read Once, Access Anytime

A more solid approach would be to read all the properties (ideally when the application is launched) and put them into memory, so they would be accessible throughout the entire lifecycle of the program. Spring makes this incredibly easy, so this is by far the recommended approach.

Example class with properties in memory.
Example class with properties in memory.

In the image above, you can see an example of a class containing application properties. It contains no business logic whatsoever. The class must be annotated with Spring’s @ConfigurationProperties annotation. You can pass a prefix value (the prefix of the property key) if so required. The nested classes cover the nested properties. The protocol property in the Mail class would be the described as cs.mail.protocol in the properties file in this case. If a property key requires editing in the future, only the key and its respective property should be adjusted in code, never more, never less.

The @Data annotation (Lombok) generates all the necessary getters and setters and it reduces boilerplate code at the same time (oh, and it makes you develop that little bit faster). You could of course provide the getters and setters yourself if you don’t want to use Lombok.

Additional Spring Configuration

Not much more left to do in order to make the properties accessible in any spring component. To follow the previous example, I’d like to bring in an example Spring configuration class:

@Configuration
@EnableConfigurationProperties({ CSProperties.class })
public class PropertiesConfig {

    private final CSProperties properties;

    @Autowired public PropertiesConfig(CSProperties properties) {
        this.properties = properties;
    }

    @Bean
    public CSProperties.Database getDatabase() {
        return properties.getDb();
    }

    @Bean
    public CSProperties.Mail getMail() {
        return properties.getMail();
    }

    @Bean
    public CSProperties.Background getBackground() {
        return properties.getBackground();
    }

    @Bean
    public CSProperties.Cache getCache() {
        return properties.getCache();
    }

What this class does is simply creating beans of the property elements. It injects our base properties class in the constructor and it creates beans of the inner classes, to make them injectable anywhere. The useful aspect of this implementation is the fact that whenever you autowire one of the subclasses, you don’t get all the other properties you don’t need. Basically you just need to grab the properties that are in scope of whatever functionality you’re developing. Obviously you can also grab al the properties whenever needed.

Since our properties class is statefull and it has getters as well as setters, we are also free to change the state of the property values while running the application. This can result in totally different application behaviour, so be careful with it. Perhaps you should add some security checks for the setters access.

To wrap things of, an example extract of a database configuration class that only injects the database properties (other properties aren’t necessary here):

private final CSProperties.Database dbProps;

    @Autowired public MyBatisConfig(CSProperties.Database dbProps) {
        this.dbProps = dbProps;
    }

    @Bean
    public DataSource dataSource() {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource ();
        dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class);
        dataSource.setUrl(dbProps.getUrl());
        dataSource.setUsername(dbProps.getUsername());
        dataSource.setPassword(dbProps.getPassword());

        return dataSource;
    }

Bonus: Property Metadata

Code completion and documentation above all. Spring actually makes it possible to attach custom metadata to your properties. IntelliJ actually detects when a property key has metadata, if so, it will provide code completion and additional information. You can also define the datatypes and default values.

Property metadata file.
Property metadata file.

Have your IDE generate a JSON file in your META-INF folder. The file will be called ‘additional-spring-configuration-metadata.json’. If you decide to use such a file, make sure to update it along with the edited property file(s).