LogoLogo
HomePricingDocumentation
  • 💿Getting Started
    • Installation and Project Setup
    • Hello Perigee!
    • Perigee Application Design
    • Hello Configuration
    • Hello Logs
    • Hello Integration
    • Troubleshooting
    • Case Studies
  • 📃License + Notice
    • 📂Licensing
    • Notice of Third Party Agreements
  • 🚀Perigee and Beyond
    • Extending - Threads
    • Extending - Loaders
    • ⏳All about CRON
  • 🔮API Generation
    • What is API Generation?
    • API Builder
  • 🗺️Architecting YOUR App
    • Design and Requirements
    • Define Sources
    • Requirements
  • 🧩Core Modules
    • 🌐PerigeeApplication
    • 🪡Thread Registry
    • Event Sources
      • Scheduled/Logic
        • CRON Thread
        • Scheduler
        • Sync Agent
      • Watchers
        • SalesForce
        • Sharepoint
        • Directory Watch
        • Directory Notifier
        • IMAP
    • Credential Management
      • Connection Strings
      • Custom Refresh Logic
      • RestSharp Authenticator
      • Credential Store SDK
      • ⁉️Troubleshooting Credentials
    • Integration Utilities
      • HTTP(S) - RestSharp
      • Transaction Coordinator
      • Limiter
      • Watermarking
    • Alert Managers
      • SMS
      • Email
      • Discord
      • Teams
    • File Formats
      • Excel
      • CSV
    • 📁File System Storage
      • File Revision Store
      • Concurrent File Store
      • FileSync + Cache
    • Third Party
      • SmartSheets
      • Microsoft Graph
    • Perigee In Parallel
      • Parallel Processing Reference
      • Extensions
      • GroupProcessor
      • SingleProcessor
    • 🧱Utility Classes
      • Metrics
      • F(x) Expressions
      • Multi-Threaded Processor (Scatter Gather)
      • OpenAI - GPT
      • XML Converter
      • Dynamic Data Table
      • Debounce
      • Thread Conditions
      • Perigee Utility Class
      • Network Utility
      • Lists
      • FileUtil
      • Inclusive2DRange
      • Strings, Numbers, Dates
      • Nested Sets
      • Behavior Trees
      • JsonCompress
      • Topological Sorting
      • DBDownloader
    • 🈁Bit Serializer
  • 📣Examples and Demos
    • API + Perigee
    • 📰Excel Quick Load
    • SalesForce Watcher
    • Report Scheduler
    • Agent Data Synchronization
    • 📩IMAP Echo bot
    • Watch and load CSVs
    • Graph Delegated Authorization + DataVerse
    • Coordinator Demo
    • Azure Service Bus
    • QuickBooks Online
  • 📘Blueprints
    • Perigee With .NET Hosting
    • Web Host Utilities
    • 🔌Plugin Load Context
  • 🎞️Transforms
    • 🌟What is Transforms?
    • 📘Terminology
    • 🦾The Mapping Document
    • 👾Transformation Process
    • 😎Profile
    • 🎒Automation
      • 🕓Package Options
      • 🔳Configuration
    • 🔧Utilities
      • 🧹Clean
      • 📑Map File
      • 🔎File Identification
      • 🗺️Map Generation
      • 🪅Insert Statement Generation
  • 🗃️Transform SDK
    • 👋Quick Start Guide
    • 🥳MapTo
    • 🔌Authoring Plugins
      • 🔘File IO Process
      • 📢Data Quality
      • 🟢Transform Process
    • SDK Reference
      • 🔘FileIOProcessData
      • 📢DataQualityContext
      • 🎛️TransformDataContext
      • 🏅TransformResult
Powered by GitBook
On this page
  • Resources
  • Sync Agents
  • Agent callbacks
  • Example - Three agents configuration
Export as PDF
  1. Examples and Demos

Agent Data Synchronization

PreviousReport SchedulerNextIMAP Echo bot

Last updated 2 years ago

Resources

Sync Agents

Sync agents are a more powerful and configurable ways of defining tasks that must perform under a given sequence, dependency tree, or schedule. They can be configured in a number of ways that allow for very complex and fine grain control over how and when they execute.

A few of examples of why we would use a sync agent:

  • A task or job needs to be fired at a given time

  • We need the ability to schedule something in a different time zone

  • We want to request that an agent performs it's refresh from a remote source (like a database)

  • The task is dependant on other tasks completing

  • We have data that may expire if not kept current

  • We need to supply multiple CRON strings to specify which times the task runs

  • We need to supply a blackout range where the task should not be executed

Agent callbacks

Agents have several main blocks to them, they are as follows:

  1. The first callback is the configuration section. We can set all kinds of settings including:

    • Maximum executions per day.

    • A timespan of how often to execute

    • An array of CRON strings to specifiy when to execute

    • Blackout periods in the form of Timespan and CRON strings.

      • Setting "* 5 * * *" as a blackout CRON would disallow the agent to run during the entire fifth hour of the day (from 5:00AM to 5:59AM inclusive)

  2. The execution callback

    • This callback is only ever called when the agent is in an active refresh/sync state.

    • You can perform whatever logic you need here, and simply return exec.Complete or exec.Failure depending on the results of your process

  3. Tree check callback

    • This callback is only for late binding trees, in the below example you can see how it's used to setup a behavior tree for checking previous agent runs

Example - Three agents configuration

In the below example we configure 3 agents.

  1. The first is run every 5 seconds, once a day.

  2. The second is run on the minute 0 mark, once a day.

  3. The level 2 agent has a late binding dependency tree to check to determine whether the first two succeeded and the data is not expired. If this is true, then it runs

using Microsoft.Extensions.Logging;
using Perigee;
using Perigee.AI;
using Perigee.Scheduler;

// Visit https://docs.perigee.software to learn more
// Visit https://perigee.software to purchase a license!


PerigeeApplication.ApplicationNoInit("Unparalleled Task Coordination", (c) => {

    //Clear on start, for demo purposes only
    if (File.Exists("MemAgent.json")) File.Delete("MemAgent.json");

    //Source
    var AgentSource = new SyncAgentSourceMemory("MemAgent.json", c.GetCancellationToken());
    
    /* PullData agent */
    c.AddAgent("PullData", "PullData", "Main", AgentSource, AgentRunCondition.RunIfPastDue,
        (configAgent) => configAgent.SetSyncLimitPerDay(1).SetSync(TimeSpan.FromSeconds(5)),
        (ct, l, exec) => {

            l.LogInformation("Pulling and loading data from remote source...");
            Task.Delay(2000).Wait();
            l.LogInformation("Done! Data is valid until {date}", DateTimeOffset.Now.AddDays(1));
            return exec.Complete(DateTimeOffset.Now.AddDays(1));
        },
        (ct, l, tree) => { });

    /* LoadExcel agent */
    c.AddAgent("LoadExcel", "LoadExcel", "Main", AgentSource, AgentRunCondition.RunIfPastDue,
        (configAgent) => configAgent.SetSyncLimitPerDay(1).SetSync(null, "0 */1 * * * *"),
        (ct, l, exec) => {

            l.LogInformation("Loading data from Excel...");
            Task.Delay(2000).Wait();
            l.LogInformation("Done! Data is valid until {date}", DateTimeOffset.Now.AddDays(1));
            return exec.Complete(DateTimeOffset.Now.AddDays(1));
        },
        (ct, l, tree) => { });


    /* Add an agent "ExecuteRefresh" that ONLY runs after the first two have produced valid data */
    c.AddAgent("ExecuteRefresh", "ExecuteRefresh", "Main", AgentSource, AgentRunCondition.RunIfPastDue,
        (configAgent) =>
            configAgent.SetSyncLimitPerDay(1).SetSync(TimeSpan.FromSeconds(5))
            .SetLateBindingBehaviorTrees(true, false),
        (ct, l, exec) => {

            l.LogInformation("Starting refresh of data now that all my sources have non expired data");
            Task.Delay(3000).Wait();
            l.LogInformation("Done! Data is valid until {date}", DateTimeOffset.Now.AddDays(1));

            return exec.Complete(DateTimeOffset.Now.AddDays(1));
        },
        (ct, l, tree) => {

            //Late binding tree update checker
            if (tree.TreeType == AgentTreeType.SyncTree)
            {
                var BT = new BehaviorTree("Check previous level completion").AddSequence("Check expiration",

                    //Returns success if the data is not expired, allowing the sequence check to proceed
                    LeafNodes.AgentDataExpired("PullData", tree.AgentData, l),
                    LeafNodes.AgentDataExpired("LoadExcel", tree.AgentData, l));

                //Set tree for late binding execution
                tree.UpdateTree(BT);

            }
        }, failedTreeReshcedule: TimeSpan.FromSeconds(15));

});
📣
Page cover image