Skip to content

Commit 4967a00

Browse files
committed
Replace MQ with Jobs, convert async to sync, session to ClaimsPrincipal
1 parent dd41a4b commit 4967a00

35 files changed

+942
-986
lines changed

BlazorDiffusion.ServiceInterface/AlbumServices.cs

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,126 +2,131 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading.Tasks;
5+
using BlazorDiffusion.ServiceInterface.App;
56
using ServiceStack;
67
using ServiceStack.OrmLite;
78
using BlazorDiffusion.ServiceModel;
9+
using ServiceStack.Jobs;
810

911
namespace BlazorDiffusion.ServiceInterface;
1012

11-
public class AlbumServices(ICrudEvents crudEvents) : Service
13+
public class AlbumServices(IBackgroundJobs jobs, ICrudEvents crudEvents) : Service
1214
{
13-
public async Task<object> Any(CreateAlbum request)
15+
public object Any(CreateAlbum request)
1416
{
1517
if (string.IsNullOrEmpty(request.Name))
1618
throw new ArgumentNullException(nameof(request.Name));
1719

1820
var slug = request.Name.GenerateSlug();
1921

20-
if (await Db.ExistsAsync<Album>(x => x.Slug == slug))
22+
if (Db.Exists<Album>(x => x.Slug == slug))
2123
throw HttpError.Conflict("Album already exists");
2224

23-
var session = await SessionAsAsync<CustomUserSession>();
25+
var userId = Request.GetRequiredUserId();
2426

2527
var album = request.ConvertTo<Album>();
26-
album.OwnerId = session.GetUserId();
28+
album.OwnerId = userId;
2729
album.OwnerRef = Db.GetUserRef(album.OwnerId);
2830
album.RefId = Guid.NewGuid().ToString("D");
2931
album.Slug = slug;
30-
album.WithAudit(session.UserAuthId);
32+
album.WithAudit(userId);
3133

32-
// TODO CrudEvents.RecordAsync
33-
album.Id = (int)await Db.InsertAsync(album, selectIdentity: true);
34-
35-
if (request.ArtifactIds?.Count > 0)
34+
lock (Locks.AppDb)
3635
{
37-
var albumArtifacts = request.ArtifactIds.Map(x => new AlbumArtifact
36+
album.Id = (int)Db.Insert(album, selectIdentity: true);
37+
38+
if (request.ArtifactIds?.Count > 0)
3839
{
39-
AlbumId = album.Id,
40-
ArtifactId = x,
41-
CreatedDate = album.CreatedDate,
42-
ModifiedDate = album.ModifiedDate,
43-
});
44-
await Db.InsertAllAsync(albumArtifacts);
45-
album.Artifacts = albumArtifacts;
46-
}
40+
var albumArtifacts = request.ArtifactIds.Map(x => new AlbumArtifact
41+
{
42+
AlbumId = album.Id,
43+
ArtifactId = x,
44+
CreatedDate = album.CreatedDate,
45+
ModifiedDate = album.ModifiedDate,
46+
});
47+
Db.InsertAll(albumArtifacts);
48+
album.Artifacts = albumArtifacts;
49+
}
4750

48-
var crudContext = CrudContext.Create<Album>(Request, Db, request, AutoCrudOperation.Create);
49-
await crudEvents.RecordAsync(crudContext);
51+
var crudContext = CrudContext.Create<Album>(Request, Db, request, AutoCrudOperation.Create);
52+
crudEvents.Record(crudContext);
53+
}
5054

5155
return album;
5256
}
5357

54-
public async Task<object> Any(UpdateAlbum request)
58+
public object Any(UpdateAlbum request)
5559
{
56-
var session = await GetSessionAsync();
57-
58-
var album = await Db.LoadSingleByIdAsync<Album>(request.Id);
60+
var album = Db.LoadSingleById<Album>(request.Id);
5961
if (album == null)
6062
throw HttpError.NotFound("Album not found");
6163

62-
if (!await session.IsOwnerOrModerator(album.OwnerId))
64+
if (!Request.IsOwnerOrModerator(album.OwnerId))
6365
throw HttpError.Forbidden("You don't own this Album");
64-
65-
using var trans = Db.OpenTransaction();
66-
var updateAlbum = request.Name != null || request.Description != null || request.Slug != null || request.Tags?.Count > 0;
67-
if (updateAlbum)
66+
67+
lock (Locks.AppDb)
6868
{
69-
if (album.Name != null)
69+
using var trans = Db.OpenTransaction();
70+
var updateAlbum = request.Name != null || request.Description != null || request.Slug != null || request.Tags?.Count > 0;
71+
if (updateAlbum)
7072
{
71-
album.Slug = album.Name.GenerateSlug();
73+
if (album.Name != null)
74+
{
75+
album.Slug = album.Name.GenerateSlug();
76+
}
77+
album.PopulateWithNonDefaultValues(request).WithAudit(Request!);
78+
Db.UpdateNonDefaults(album, x => x.Id == album.Id);
7279
}
73-
album.PopulateWithNonDefaultValues(request).WithAudit(session.UserAuthId);
74-
await Db.UpdateNonDefaultsAsync(album, x => x.Id == album.Id);
75-
}
7680

77-
if (request.RemoveArtifactIds?.Count > 0)
78-
{
79-
await Db.DeleteAsync<AlbumArtifact>(x => x.AlbumId == album.Id && request.RemoveArtifactIds.Contains(x.ArtifactId));
80-
// Delete Album if it no longer contains any Artifacts
81-
if (!await Db.ExistsAsync<AlbumArtifact>(x => x.AlbumId == album.Id))
81+
if (request.RemoveArtifactIds?.Count > 0)
8282
{
83-
await Db.DeleteByIdAsync<Album>(album.Id);
83+
Db.Delete<AlbumArtifact>(x => x.AlbumId == album.Id && request.RemoveArtifactIds.Contains(x.ArtifactId));
84+
// Delete Album if it no longer contains any Artifacts
85+
if (!Db.Exists<AlbumArtifact>(x => x.AlbumId == album.Id))
86+
{
87+
Db.DeleteById<Album>(album.Id);
88+
}
89+
else if (album.PrimaryArtifactId != null && request.RemoveArtifactIds.Contains(album.PrimaryArtifactId.Value))
90+
{
91+
Db.UpdateOnly(() => new Album { PrimaryArtifactId = null }, where: x => x.Id == album.Id);
92+
}
93+
album.Artifacts.RemoveAll(x => request.RemoveArtifactIds.Contains(x.ArtifactId)); // required so they get added below
94+
request.RemoveArtifactIds.ForEach(Updated.ArtifactIds.Add); //rerender artifact .html
8495
}
85-
else if (album.PrimaryArtifactId != null && request.RemoveArtifactIds.Contains(album.PrimaryArtifactId.Value))
96+
if (request.AddArtifactIds?.Count > 0)
8697
{
87-
await Db.UpdateOnlyAsync(() => new Album { PrimaryArtifactId = null }, where: x => x.Id == album.Id);
98+
var albumArtifacts = request.AddArtifactIds.Where(x => album.Artifacts.OrEmpty().All(a => a.ArtifactId != x))
99+
.Map(x => new AlbumArtifact
100+
{
101+
AlbumId = album.Id,
102+
ArtifactId = x,
103+
CreatedDate = album.CreatedDate,
104+
ModifiedDate = album.ModifiedDate,
105+
});
106+
Db.InsertAll(albumArtifacts);
107+
request.AddArtifactIds.ForEach(Updated.ArtifactIds.Add); //rerender artifact .html
108+
}
109+
if (request.PrimaryArtifactId != null)
110+
{
111+
if (request.UnpinPrimaryArtifact != true)
112+
Db.UpdateOnly(() => new Album { PrimaryArtifactId = request.PrimaryArtifactId }, where: x => x.Id == album.Id);
113+
else
114+
Db.UpdateOnly(() => new Album { PrimaryArtifactId = null }, where: x => x.Id == album.Id);
88115
}
89-
album.Artifacts.RemoveAll(x => request.RemoveArtifactIds.Contains(x.ArtifactId)); // required so they get added below
90-
request.RemoveArtifactIds.ForEach(Updated.ArtifactIds.Add); //rerender artifact .html
91-
}
92-
if (request.AddArtifactIds?.Count > 0)
93-
{
94-
var albumArtifacts = request.AddArtifactIds.Where(x => album.Artifacts.OrEmpty().All(a => a.ArtifactId != x))
95-
.Map(x => new AlbumArtifact
96-
{
97-
AlbumId = album.Id,
98-
ArtifactId = x,
99-
CreatedDate = album.CreatedDate,
100-
ModifiedDate = album.ModifiedDate,
101-
});
102-
await Db.InsertAllAsync(albumArtifacts);
103-
request.AddArtifactIds.ForEach(Updated.ArtifactIds.Add); //rerender artifact .html
104-
}
105-
if (request.PrimaryArtifactId != null)
106-
{
107-
if (request.UnpinPrimaryArtifact != true)
108-
await Db.UpdateOnlyAsync(() => new Album { PrimaryArtifactId = request.PrimaryArtifactId }, where: x => x.Id == album.Id);
109-
else
110-
await Db.UpdateOnlyAsync(() => new Album { PrimaryArtifactId = null }, where: x => x.Id == album.Id);
111-
}
112116

113-
if (updateAlbum)
114-
{
115-
var crudContext = CrudContext.Create<Album>(Request, Db, request, AutoCrudOperation.Patch);
116-
await crudEvents.RecordAsync(crudContext);
117-
}
117+
if (updateAlbum)
118+
{
119+
var crudContext = CrudContext.Create<Album>(Request, Db, request, AutoCrudOperation.Patch);
120+
crudEvents.Record(crudContext);
121+
}
118122

119-
trans.Commit();
123+
trans.Commit();
120124

121-
PublishMessage(new BackgroundTasks {
122-
ArtifactIdsAddedToAlbums = request.AddArtifactIds,
123-
ArtifactIdsRemovedFromAlbums = request.RemoveArtifactIds,
124-
});
125+
jobs.RunCommand<UpdateScoresCommand>(new UpdateScores {
126+
ArtifactIdsAddedToAlbums = request.AddArtifactIds,
127+
ArtifactIdsRemovedFromAlbums = request.RemoveArtifactIds,
128+
});
129+
}
125130

126131
return album;
127132
}
@@ -146,7 +151,7 @@ public async Task<object> Any(GetCreativesInAlbums request)
146151
artifact.ArtifactId,
147152
});
148153

149-
var albumRefs = await Db.SelectAsync<AlbumArtifactResult>(q);
154+
var albumRefs = Db.Select<AlbumArtifactResult>(q);
150155

151156
var albumMap = new Dictionary<int, AlbumResult>();
152157
foreach (var albumRef in albumRefs)
@@ -162,8 +167,8 @@ public async Task<object> Any(GetCreativesInAlbums request)
162167
OwnerRef = albumRef.OwnerRef,
163168
Score = albumRef.Score,
164169
ArtifactIds = albumRef.PrimaryArtifactId != null
165-
? new() { albumRef.PrimaryArtifactId.Value }
166-
: new(),
170+
? [albumRef.PrimaryArtifactId.Value]
171+
: [],
167172
};
168173

169174
album.ArtifactIds.AddIfNotExists(albumRef.ArtifactId);
@@ -175,30 +180,36 @@ public async Task<object> Any(GetCreativesInAlbums request)
175180
};
176181
}
177182

178-
public async Task<object> Post(CreateAlbumLike request)
183+
public object Post(CreateAlbumLike request)
179184
{
180-
var session = await SessionAsAsync<CustomUserSession>();
181-
var userId = session.GetUserId();
185+
var userId = Request.GetRequiredUserId();
182186
var row = new AlbumLike
183187
{
184188
AppUserId = userId,
185189
AlbumId = request.AlbumId,
186190
CreatedDate = DateTime.UtcNow,
187191
};
188-
row.Id = await base.Db.InsertAsync(row, selectIdentity: true);
192+
lock (Locks.AppDb)
193+
{
194+
row.Id = base.Db.Insert(row, selectIdentity: true);
195+
}
189196

190-
PublishMessage(new BackgroundTasks { RecordAlbumLikeId = request.AlbumId });
197+
jobs.RunCommand<UpdateScoresCommand>(new UpdateScores {
198+
RecordAlbumLikeId = request.AlbumId
199+
});
191200
return row;
192201
}
193202

194203
public async Task Delete(DeleteAlbumLike request)
195204
{
196-
var session = await SessionAsAsync<CustomUserSession>();
197-
var userId = session.GetUserId();
198-
await Db.DeleteAsync<AlbumLike>(x => x.AlbumId == request.AlbumId && x.AppUserId == userId);
205+
var userId = Request.GetRequiredUserId();
206+
lock (Locks.AppDb)
207+
{
208+
Db.Delete<AlbumLike>(x => x.AlbumId == request.AlbumId && x.AppUserId == userId);
209+
}
199210

200-
PublishMessage(new BackgroundTasks { RecordAlbumUnlikeId = request.AlbumId });
211+
jobs.RunCommand<UpdateScoresCommand>(new UpdateScores {
212+
RecordAlbumUnlikeId = request.AlbumId
213+
});
201214
}
202-
203-
204215
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using BlazorDiffusion.ServiceModel;
2+
using Microsoft.Extensions.Logging;
3+
using ServiceStack;
4+
using ServiceStack.Data;
5+
using ServiceStack.Jobs;
6+
using ServiceStack.OrmLite;
7+
8+
namespace BlazorDiffusion.ServiceInterface.Analytics;
9+
10+
public class RecordAnalytics
11+
{
12+
public SearchStat? RecordSearchStat { get; set; }
13+
public ArtifactStat? RecordArtifactStat { get; set; }
14+
}
15+
16+
[Worker(Databases.Analytics)]
17+
public class RecordAnalyticsCommand(ILogger<RecordAnalyticsCommand> logger, IBackgroundJobs jobs, IDbConnectionFactory dbFactory) : SyncCommand<RecordAnalytics>
18+
{
19+
protected override void Run(RecordAnalytics request)
20+
{
21+
using var db = dbFactory.OpenDbConnection();
22+
if (request.RecordArtifactStat != null && !Users.IsAdminOrSystem(request.RecordArtifactStat.AppUserId))
23+
{
24+
using var analyticsDb = HostContext.AppHost.GetDbConnection(Databases.Analytics);
25+
analyticsDb.Insert(request.RecordArtifactStat);
26+
27+
if (request.RecordArtifactStat.Type == StatType.Download)
28+
Scores.IncrementArtifactDownload(db, request.RecordArtifactStat.ArtifactId);
29+
}
30+
31+
if (request.RecordSearchStat != null && !Users.IsAdminOrSystem(request.RecordSearchStat.AppUserId))
32+
{
33+
using var analyticsDb = HostContext.AppHost.GetDbConnection(Databases.Analytics);
34+
analyticsDb.Insert(request.RecordSearchStat);
35+
36+
if (request.RecordSearchStat.ArtifactId != null)
37+
Scores.IncrementArtifactSearch(db, request.RecordSearchStat.ArtifactId.Value);
38+
39+
if (request.RecordSearchStat.Source != AppSource.Top)
40+
{
41+
var albumId = request.RecordSearchStat.AlbumId
42+
?? (request.RecordSearchStat.Album != null
43+
? db.Scalar<int>(db.From<Album>()
44+
.Where(x => x.RefId == request.RecordSearchStat.Album)
45+
.Select(x => x.Id))
46+
: null);
47+
if (albumId != null)
48+
Scores.IncrementAlbumSearch(db, albumId.Value);
49+
}
50+
}
51+
}
52+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Data;
2+
using BlazorDiffusion.ServiceModel;
3+
using ServiceStack;
4+
using ServiceStack.OrmLite;
5+
6+
namespace BlazorDiffusion.ServiceInterface.App;
7+
8+
public class CreateCreativeCommand(IDbConnection db) : SyncCommand<Creative>
9+
{
10+
protected override void Run(Creative creative)
11+
{
12+
var ftsArtifacts = creative.Artifacts.Map(x => new ArtifactFts
13+
{
14+
rowid = x.Id,
15+
Prompt = creative.Prompt,
16+
CreativeId = creative.Id,
17+
RefId = x.RefId,
18+
});
19+
db.InsertAll(ftsArtifacts);
20+
// If retry callbacks fire, they will fail since there is no CreativeQueue reference.
21+
db.Delete<CreativeQueue>(x => x.RefId == creative.RefId);
22+
}
23+
}

0 commit comments

Comments
 (0)