summaryrefslogtreecommitdiff
path: root/src/marlin.agents.shell/SlaveLoop.cs
blob: 82f6ff59f5d34b80552ca9f400895ccd2a5a0f8d (plain)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
namespace marlin.agents.shell;

using System.Runtime.InteropServices;
using core.contracts;
using core.functional;
using core.models;
using core.util;
using ProtoBuf.Grpc.Client;

public class SlaveLoop
{
    private static readonly string _jobInstanceDir = Path.Combine(CommonPaths.AgentRoot, "instance");
    private readonly MarlinApiClient _client;

    public SlaveLoop()
    {
        this._client = MarlinApiClient.FromEnvironment();
    }
    
    public async Task Start()
    {
        AgentConfiguration config = await Handshake();
        Console.WriteLine($"IAM: {config.Name}");
        Console.WriteLine($"MCJ: {config.MaxConcurrentJobs}");

        while (true)
        {
            var job = await this._client.QueueNextJob();
            if (job == null)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                continue;
            }
            
            Console.WriteLine($"Claimed job {job.Id}: {job.Recipe}");
            await FireJob(job);
        }
    }
    
    private async Task<AgentConfiguration> Handshake()
    {
        var capabilities = new CapabilitySet();
        capabilities.Items.Add(KnownCapabilities.Architecture, RuntimeInformation.OSArchitecture.ToString());
        capabilities.Items.Add(KnownCapabilities.CoreCount, Environment.ProcessorCount.ToString());
        capabilities.Items.Add(KnownCapabilities.Memory, (GC.GetGCMemoryInfo().TotalAvailableMemoryBytes / (1024 * 1024)).ToString());
        var status = new AgentStatus(capabilities);

        AgentConfiguration config = await _client.Handshake(status);
        return config;
    }
    
    private async Task FireJob(DispatchJob job)
    {
        GitBinaryClient gitClient = new();
        var channel = this._client.CreateJobScopedRpc(job);
        var instanceService = channel.CreateGrpcService<IInstanceService>();

        string workingDir = Path.Combine(_jobInstanceDir, job.Id.ToString("N"));
        
        Directory.CreateDirectory(_jobInstanceDir);
        if (Path.Exists(workingDir))
            Directory.Delete(workingDir, true);
        
        await gitClient.Checkout(workingDir, job.Vcs, job.Ref, job.Commit);

        var uow = new JobUnitOfWork(instanceService, workingDir, job.Recipe);
        await uow.Run();
    }
}