Daemons

A daemon is task that runs in the background at a specified schedule.

Model

To add a daemon you should first add a class that inherits from Daemon class. A good convention to follow is placing your class in the Models folder. In the example below we add a daemon that sends a daily email with the current number of Spaces, Spaces, and Users in the system.

using System;
using System.ComponentModel.DataAnnotations;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Threading;
using Weavy.Core;
using Weavy.Core.Models;
using Weavy.Core.Plugins;
using Weavy.Core.Services;

namespace Weavy.Models {

    [Serializable]
    [Guid("B76F56D7-4498-41E6-A0D9-1CD8663ECBCF")]
    [Daemon(Icon = "chart-bar", Name = "Statistics report", Description = "Sends an email with current system usage.", Schedule = "0 4 * * *")]
    public class StatsReportDaemon : Daemon {

        [Required]
        [EmailAddress]
        [Display(Name = "Email address", Description = "Email address where to send the report.")]
        public string Email { get; set; }

        /// <summary>
        /// Send a report with current system usage to the specified email address.
        /// </summary>
        /// <param name="token"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override bool Run(CancellationToken token, params string[] args) {
            token.ThrowIfCancellationRequested();
            try {
                var stats = StatisticsService.Sample();
                var settings = SettingService.Get<SmtpSettings>();
                var message = new MailMessage(
                    settings.From,
                    Email, 
                    "Statistics report", 
                    $@"Current usage stats for {WeavyContext.Current.System.Name}:

                    Apps: {stats.AppCount}                    
                    Spaces: {stats.SpaceCount}
                    Users: {stats.UserCount}"
                );
                MailService.Send(message);

                Output.WriteLine($@"Statistics report sent!");
                return true;
            } catch (Exception ex) {
                Output.WriteLine(ex.Message);
            }
            return false;
        }
    }
}

Class attributes

As shown above, daemons must be decorated with the [Serializable] and [Guid] attributes.

Make sure to give your class a unique Guid, otherwise it will not be recognized by Weavy.

To further customize your daemon you can also decorate it with the [Daemon] attribute. Some of the properties you can set are:

  • Icon – name of an icon to use when displaying the daemon.
  • Colorcolor to use for the icon.
  • Name – display name for the content item, e.g. “Statistics report”.
  • Description – a description to use for the daemon, e.g “Sends an email with current system usage.”.
  • Schedule – a crontab expression representing the schedule when the daemon should run.

Fields

Daemon fields are pieces of information that can be added to a daemon. This can be useful if your daemon requires some kind of configuration or settings. Daemon fields have a name and a type. In the example above, we added a field for storing the Email address where the report should be sent.

For a property to be considered a daemon field, it must be declared as public read-write, i.e. the property has the public access modifier and have both a get and a set accessor.

Daemon fields must also have one of the following supported types:

  • enum
  • byte
  • short
  • int
  • long
  • bool
  • double
  • float
  • string
  • Guid
  • DateTime
  • TimeSpan

Nullables and Lists of the above types are also supported, e.g. int?, List<string> and List<DateTime?>.

Field attributes

By decorating your fields with one, or more, of the following attributes you can customize how the field is displayed, edited and/or validated.

Datatype

By default, Weavy will look at the property type (in this case IList<string>) when deciding which editor to use for the field. By decorating a field with the [DataType] attribute you can specify an additional type to associate with the field. This value will then be used by the UI to determine which editor to use for the field.

[DataType(DataType.EmailAddress)]
public string Email { get; set; }

Here we specify that the Email field should be treated as an email address instead of a plain string.

Display

The [Display] attribute lets you specify a name and description to use for the field.

[Display(Name = "Email address", Description = "Email address where to send the report.")]
public string Email { get; set; }
Validation

By adding one, or more, [Validation] attributes to your fields you can control how they are validated.

[Required]
[EmailAddress]
public string Email { get; set; }

Here we specify that the Email property is required and that is should be validated as an email address.

For full control of validation you can let your class implement IValidatableObject and add your own validation logic.

Configuration

If a daemon requires some kind of configuration settings, like the Email property in our StatsReportDaemon, you can navigate to /manage/daemons/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where the last segment should be replaced with the Guid of your Daemon, in this case B76F56D7-4498-41E6-A0D9-1CD8663ECBCF for the StatsReportDaemon.