using AIStudio.Settings; using AIStudio.Settings.DataModel; namespace AIStudio.Tools.Services.Indexing; /// /// The bounds of the random pause between two indexing steps, cf. PauseBetweenSteps. /// /// The shortest pause. Between zero and MaximumSeconds. /// The longest pause, which may be drawn as well. At most DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS. internal sealed record PauseRange(int MinimumSeconds, int MaximumSeconds) { /// /// No pause at all, which is the default. /// public static readonly PauseRange NONE = new(0, 0); /// /// Whether the next step starts right away. /// public bool IsNone => this.MaximumSeconds is 0; /// /// The bounds which apply now, as the user set them and as configuration plugins lock them. /// /// The settings of the indexing. /// The bounds which apply. public static PauseRange FromSettings(DataDataSourceIndexing settings) { var minimumSeconds = settings.MinimumPauseBetweenStepsSeconds; var maximumSeconds = settings.MaximumPauseBetweenStepsSeconds; // // Which bound a configuration plugin locks matters only while the bounds are the wrong way // round. Asking reads the managed state of the whole app, which bounds in order do without: // if (minimumSeconds <= maximumSeconds) return GetEffective(minimumSeconds, false, maximumSeconds, false); var isMinimumLocked = ManagedConfiguration.TryGet(x => x.App.DataSourceIndexing, x => x.MinimumPauseBetweenStepsSeconds, out var minimumMeta) && minimumMeta.IsLocked; var isMaximumLocked = ManagedConfiguration.TryGet(x => x.App.DataSourceIndexing, x => x.MaximumPauseBetweenStepsSeconds, out var maximumMeta) && maximumMeta.IsLocked; return GetEffective(minimumSeconds, isMinimumLocked, maximumSeconds, isMaximumLocked); } /// /// Works out the bounds which apply, so that the lower one never exceeds the upper one. /// /// /// A bound which a configuration plugin locks wins, and the other one adjusts to it. A bound the /// plugin only presets counts like one the user set. Otherwise, the lower bound wins, i.e., the /// longer pause: it spares the embedding server, which is what the pause is for. That holds as /// well when a plugin locks both bounds the wrong way round. /// /// The lower bound as set. /// Whether a configuration plugin locks the lower bound. /// The upper bound as set. /// Whether a configuration plugin locks the upper bound. /// The bounds which apply. public static PauseRange GetEffective(int minimumSeconds, bool isMinimumLocked, int maximumSeconds, bool isMaximumLocked) { var minimum = Math.Clamp(minimumSeconds, 0, DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS); var maximum = Math.Clamp(maximumSeconds, 0, DataDataSourceIndexing.MAX_PAUSE_BETWEEN_STEPS_SECONDS); if (isMaximumLocked && !isMinimumLocked) return new(Math.Min(minimum, maximum), maximum); return new(minimum, Math.Max(minimum, maximum)); } }