aboutsummaryrefslogtreecommitdiff
path: root/Plugins/SessionProvider/SessionClientEntryPoint.cs
blob: ed62d4cd8689487cf0c9dad02f747e7ee1a3e089 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

using VNLib.Net.Http;
using VNLib.Utils.Logging;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Essentials.Sessions.Runtime;

namespace VNLib.Plugins.Essentials.Sessions
{
    /// <summary>
    /// The implementation type for dynamic loading of unified session providers 
    /// </summary>
    public sealed class SessionClientEntryPoint : PluginBase, ISessionProvider
    {        
        public override string PluginName => "Essentials.Sessions";

        
        private readonly List<AssemblyLoader<IRuntimeSessionProvider>> ProviderLoaders = new();

        private IRuntimeSessionProvider[] ProviderArray = Array.Empty<IRuntimeSessionProvider>();
        

        ValueTask<SessionHandle> ISessionProvider.GetSessionAsync(IHttpEvent entity, CancellationToken token)
        {
            //Loop through providers
            for (int i = 0; i < ProviderArray.Length; i++)
            {
                //Check if provider can process the entity
                if (ProviderArray[i].CanProcess(entity))
                {
                    //Get session
                    return ProviderArray[i].GetSessionAsync(entity, token);
                }
            }

            //Return empty session
            return new ValueTask<SessionHandle>(SessionHandle.Empty);
        }

        protected override void OnLoad()
        {
            try
            {
                Log.Verbose("Loading all specified session providers");

                //Get all provider names
                IEnumerable<string> providerAssemblyNames = PluginConfig.GetProperty("provider_assemblies")
                                                .EnumerateArray()
                                                .Where(s => s.GetString() != null)
                                                .Select(s => s.GetString()!);
                
               
                foreach(string asm in providerAssemblyNames)
                {
                    Log.Verbose("Loading {dll} session provider", asm);
    
                    //Attempt to load provider
                    AssemblyLoader<IRuntimeSessionProvider> prov =  this.LoadAssembly<IRuntimeSessionProvider>(asm);

                    //Create localized log
                    LocalizedLogProvider log = new(Log, $"{Path.GetFileName(asm)}");

                    //Try to load the websessions
                    prov.Resource.Load(this, log);

                    //Add provider to list
                    ProviderLoaders.Add(prov);
                }

                if(ProviderLoaders.Count > 0)
                {
                    //Create array for searching for providers
                    ProviderArray = ProviderLoaders.Select(s => s.Resource).ToArray();

                    Log.Information("Loaded {count} session providers", ProviderArray.Length);
                }
                else
                {
                    Log.Information("No session providers loaded");
                }

                Log.Information("Plugin loaded");
            }
            catch (KeyNotFoundException knf)
            {
                //Dispose providers
                ProviderLoaders.ForEach(s => s.Dispose());

                Log.Warn("Plugin configuration was missing required variables {var}", knf.Message);
            }
            catch
            {
                //Dispose providers
                ProviderLoaders.ForEach(s => s.Dispose());
                throw;
            }
        }
      
        protected override void OnUnLoad()
        {
            //Clear array
            ProviderArray = Array.Empty<IRuntimeSessionProvider>();

            //Cleanup assemblies
            ProviderLoaders.ForEach(p => p.Dispose());
            ProviderLoaders.Clear();

            Log.Information("Plugin unloaded");
        }

        protected override void ProcessHostCommand(string cmd)
        {
            if (!this.IsDebug())
            {
                return;
            }
        }
    }
}