Files
Libation/Source/DataLayer.Postgres/Migrations/20260816160446_AddDownloadAttemptFailures.cs
Cursor Agentandrmcrackan 824ff10dd9 fix(download): stop asking Audible for a license it just refused
A license denial left no trace: BookStatus stayed NotLiberated, so every
liberate run asked again. Only the GUI's bad-book dialog could mark a title
Error, and license denials take their own path and never reach that dialog, so
a headless install had no way at all to stop the retries. A cron schedule then
re-requested the same refused licenses every run and printed the same warning
block for each one, which is both wasted API traffic and the log noise reported
in issue #1947.

Record the refusal instead, with a wait that doubles per consecutive failure:
one day for an eligibility denial (up to 30), six hours for a title Audible has
no audio for yet such as an unreleased preorder (up to 7 days), one hour when
the denial names GenericError, which the GUI already reads as an outage
(up to 12). Nothing is permanent - every kind is attempted again on its own.

Only failures attributable to Audible are recorded. A dropped connection, a
decrypt error or a full disk keeps being retried on the next run as before.

Naming a title, --force, and setting a download status all clear the record:
asking for a title explicitly overrides the wait.

Co-authored-by: rmcrackan <rmcrackan@gmail.com>
2026-08-16 16:13:17 +00:00

48 lines
2.0 KiB
C#

using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DataLayer.Postgres.Migrations
{
/// <inheritdoc />
public partial class AddDownloadAttemptFailures : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "DownloadAttemptFailures",
columns: table => new
{
DownloadAttemptFailureId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AudibleProductId = table.Column<string>(type: "text", nullable: false),
Account = table.Column<string>(type: "text", nullable: false),
Kind = table.Column<int>(type: "integer", nullable: false),
ConsecutiveFailures = table.Column<int>(type: "integer", nullable: false),
LastFailedAtUtcTicks = table.Column<long>(type: "bigint", nullable: false),
RetryAfterUtcTicks = table.Column<long>(type: "bigint", nullable: false),
Reason = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_DownloadAttemptFailures", x => x.DownloadAttemptFailureId);
});
migrationBuilder.CreateIndex(
name: "IX_DownloadAttemptFailures_Account_AudibleProductId",
table: "DownloadAttemptFailures",
columns: new[] { "Account", "AudibleProductId" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DownloadAttemptFailures");
}
}
}