Skip to content

Commit d87c68b

Browse files
Techbot121Meta Construct
authored andcommitted
this should work now
1 parent c31cdab commit d87c68b

File tree

4 files changed

+48
-37
lines changed

4 files changed

+48
-37
lines changed

app/Container.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export class Container {
77
readonly app: App;
88
private providers: ProviderFactory;
99
private services = {} as ServiceMap;
10-
private initPromises = new Map<string, Promise<Service>>();
10+
private pendingServices = new Map<string, Promise<Service>>();
1111

1212
constructor(app: App, providers: ProviderFactory) {
1313
this.app = app;
@@ -27,40 +27,43 @@ export class Container {
2727
service = await service;
2828
}
2929
this.services[service.name] = service;
30-
}
3130

32-
async getService<T extends keyof ServiceMap>(name: T): Promise<ServiceMap[T]> {
33-
const service = this.services[name];
34-
if (service) {
35-
return service as ServiceMap[T];
31+
// Resolve any pending waiters
32+
const pendingPromise = this.pendingServices.get(service.name);
33+
if (pendingPromise) {
34+
this.pendingServices.delete(service.name);
3635
}
36+
}
3737

38-
// If already initializing, wait for it
39-
if (this.initPromises.has(String(name))) {
40-
return this.initPromises.get(String(name)) as Promise<ServiceMap[T]>;
38+
async getService<Name extends string>(
39+
type: Name,
40+
timeoutMs = 30000
41+
): Promise<ServiceMap[Name]> {
42+
if (this.services[type]) {
43+
return this.services[type];
4144
}
4245

43-
// Find the provider
44-
const provider = this.providers.find(p => {
45-
const temp = p(this);
46-
if (temp instanceof Promise) {
47-
return temp.then(s => s.name === name);
48-
}
49-
return temp.name === name;
50-
});
46+
// Create or return existing promise for this service
47+
if (!this.pendingServices.has(type)) {
48+
this.pendingServices.set(
49+
type,
50+
new Promise((resolve, reject) => {
51+
const timeoutId = setTimeout(() => {
52+
this.pendingServices.delete(type);
53+
reject(new Error(`Timeout waiting for service: ${type}`));
54+
}, timeoutMs);
5155

52-
if (!provider) {
53-
throw new Error(`Service ${String(name)} not found`);
56+
const checkInterval = setInterval(() => {
57+
if (this.services[type]) {
58+
clearTimeout(timeoutId);
59+
clearInterval(checkInterval);
60+
resolve(this.services[type]);
61+
}
62+
}, 100);
63+
})
64+
);
5465
}
5566

56-
// Initialize the service
57-
const promise = Promise.resolve(provider(this)).then(service => {
58-
this.services[name] = service;
59-
this.initPromises.delete(String(name));
60-
return service as ServiceMap[T];
61-
});
62-
63-
this.initPromises.set(String(name), promise);
64-
return promise;
67+
return this.pendingServices.get(type) as Promise<ServiceMap[Name]>;
6568
}
6669
}

app/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ export class App {
66

77
constructor() {
88
this.container = new Container(this, providers);
9+
10+
this.init();
11+
}
12+
13+
async init(): Promise<void> {
14+
for (const provider of this.container.getProviders()) {
15+
await this.container.addService(provider(this.container));
16+
}
917
}
1018
}

app/services/discord/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export class DiscordBot extends Service {
4646
super(container);
4747

4848
this.initServices();
49+
}
50+
51+
private async initServices() {
52+
this.data = await this.container.getService("Data");
53+
this.bridge = await this.container.getService("GameBridge");
4954

5055
this.discord.on("ready", async client => {
5156
this.ready = true;
@@ -64,11 +69,6 @@ export class DiscordBot extends Service {
6469

6570
this.discord.login(this.config.bot.token);
6671
}
67-
68-
private async initServices() {
69-
this.data = await this.container.getService("Data");
70-
this.bridge = await this.container.getService("GameBridge");
71-
}
7272
getTextChannel(channelId: string): Discord.TextChannel | undefined {
7373
if (!this.ready) return;
7474
return this.discord.channels.cache.get(channelId) as Discord.TextChannel;

app/services/gamebridge/GameBridge.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export default class GameBridge extends Service {
2626
constructor(container: Container) {
2727
super(container);
2828
this.setupWebApp();
29+
}
30+
31+
private async setupWebApp() {
32+
this.webApp = await this.container.getService("WebApp");
2933
this.ws = new WebSocketServer({
3034
httpServer: this.webApp.http,
3135
autoAcceptConnections: false,
@@ -39,10 +43,6 @@ export default class GameBridge extends Service {
3943
this.handleResoniteConnection();
4044
}
4145

42-
private async setupWebApp() {
43-
this.webApp = await this.container.getService("WebApp");
44-
}
45-
4646
async handleConnection(req: WebSocketRequest): Promise<void> {
4747
const ip = req.httpRequest.socket.remoteAddress;
4848

0 commit comments

Comments
 (0)