@social-mail/social-mail-web-server 1.7.463 → 1.7.464

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.7.463",
3
+ "version": "1.7.464",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -16,6 +16,7 @@ import CachedItem from "../../model/entities/CachedItem.js";
16
16
  import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
17
17
  import { appendFile } from "fs/promises";
18
18
  import DbLockService from "../db-lock/DbLockService.js";
19
+ import RateLimiterService from "../rate-limiter/RateLimiterService.js";
19
20
 
20
21
  export class CachedFile implements Disposable {
21
22
 
@@ -52,6 +53,9 @@ export default class CacheService {
52
53
  @Inject
53
54
  private dbLockService: DbLockService;
54
55
 
56
+ @Inject
57
+ private rateLimiter: RateLimiterService;
58
+
55
59
  public async clear() {
56
60
  const now = DateTime.now;
57
61
  const files = await this.db.cachedItems.where({ now }, (p) => (x) => x.expiry <= p.now)
@@ -125,13 +129,18 @@ export default class CacheService {
125
129
  }
126
130
 
127
131
 
128
- public async get({
129
- key,
130
- ttl,
131
- factory
132
- }: { key: string, ttl: TimeSpan, factory: (c?: CachedItem) => Promise<LocalFile> }) {
132
+ public async get(ck: { key: string, ttl: TimeSpan, factory: (c?: CachedItem) => Promise<LocalFile> }) {
133
+
134
+ const {
135
+ key,
136
+ ttl,
137
+ factory
138
+ } = ck;
139
+
133
140
  const now = DateTime.now;
134
141
 
142
+ await using rl = await this.rateLimiter.acquireDisposable("0.0.0.0", "file-cache", 1/10);
143
+
135
144
  const keyHash = await this.cryptoService.hashBuffer(Buffer.from(key, "utf-8"));
136
145
 
137
146
  await using dbLock = await this.dbLockService.lock(`ci-${keyHash}`, DateTime.now.addMinutes(5));
@@ -155,11 +164,7 @@ export default class CacheService {
155
164
  },{ itemID: cachedItem.itemID });
156
165
  }
157
166
  cloudPath = `cache/${cachedItem.itemID}`;
158
- try {
159
- return await this.tempFileService.downloadCloudFile(cloudPath, fileName);
160
- } catch (error) {
161
- console.error(error);
162
- }
167
+ return this.downloadCachedFile(ck, cachedItem, cloudPath, fileName);
163
168
  }
164
169
  cachedItem.expiry = DateTime.now.addDays(30);
165
170
  await this.db.cachedItems.statements.update({
@@ -198,6 +203,17 @@ export default class CacheService {
198
203
  return await this.tempFileService.downloadCloudFile(cloudPath, fileName);
199
204
  }
200
205
 
206
+ async downloadCachedFile(ck, c: CachedItem, cloudPath: string, fileName: string) {
207
+ try {
208
+ return await this.tempFileService.downloadCloudFile(cloudPath, fileName);
209
+ } catch (error) {
210
+ await this.db.cachedItems.statements.delete({ itemID: c.itemID });
211
+ return this.get(ck);
212
+ console.error(error);
213
+ }
214
+
215
+ }
216
+
201
217
 
202
218
  // private async lockCachedItem(item: CachedItem, max = DateTime.now.addMinutes(1)) {
203
219
 
@@ -46,7 +46,7 @@ export default class FileConversionService {
46
46
  return await this.cacheService.get({ key, ttl,
47
47
  factory: async () => {
48
48
 
49
- await using tx = await this.rateLimiterService.expirableAcquire("any", "ic" + process.pid , 2);
49
+ await using tx = await this.rateLimiterService.acquireDisposable("any", "ic" + process.pid , 2);
50
50
 
51
51
  file = await this.downloadFileContent(appFile, fileContentID);
52
52
  // resize...
@@ -59,7 +59,7 @@ export default class FileConversionService {
59
59
  if (/^(pdf|html|webm(\-branded)?)$/i.test(type)) {
60
60
  return await this.cacheService.get({ key, ttl,
61
61
  factory: async () => {
62
- await using tx = await this.rateLimiterService.expirableAcquire("any", "vc" + process.pid, 1);
62
+ await using tx = await this.rateLimiterService.acquireDisposable("any", "vc" + process.pid, 1);
63
63
  file = await this.downloadFileContent(appFile, fileContentID);
64
64
  const ics = this;
65
65
  return await ics[StringFormat.toCamelCase(type)](file, fileName );
@@ -47,7 +47,11 @@ export default class RateLimiterService {
47
47
  return null;
48
48
  }
49
49
 
50
- async expirableAcquire(ip: string, group: string, maxPerSecond = 1/15 ) {
50
+ async acquireDisposable(
51
+ ip: string,
52
+ group: string,
53
+ maxPerSecond = 1/15
54
+ ) {
51
55
  const { db } = this;
52
56
  let now = DateTime.now;
53
57