Skip to content

Commit

Permalink
feat: add server.clean method (#830)
Browse files Browse the repository at this point in the history
Like `factory.clean`, `server.clean` shuts down any running Kubo
nodes created by the server and removes references to them.
  • Loading branch information
achingbrain authored Apr 26, 2024
1 parent b424960 commit 855bec9
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 23 deletions.
5 changes: 1 addition & 4 deletions src/endpoint/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ const badRequest = (err: Error & { stdout?: string }): void => {
throw boom.badRequest(msg)
}

const nodes: Record<string, Node> = {}

export default (server: Server, createFactory: () => Factory | Promise<Factory>): void => {
export default (server: Server, ipfsd: Factory, nodes: Record<string, Node>): void => {
/**
* Spawn a controller
*/
Expand All @@ -38,7 +36,6 @@ export default (server: Server, createFactory: () => Factory | Promise<Factory>)
handler: async (request) => {
const options: any = request.payload ?? {}
try {
const ipfsd = await createFactory()
const id = nanoid()
nodes[id] = await ipfsd.spawn({
...options,
Expand Down
31 changes: 22 additions & 9 deletions src/endpoint/server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import Hapi from '@hapi/hapi'
import routes from './routes.js'
import type { Factory } from '../index.js'

interface CreateFactory {
(): Factory
}
import type { Node, Factory } from '../index.js'

export interface ServerInit {
port?: number
Expand All @@ -19,14 +15,16 @@ class Server {
private server: Hapi.Server | null
public port: number
public host: string
private readonly createFactory: CreateFactory
private readonly ipfsd: Factory
public readonly nodes: Record<string, Node>

constructor (options: ServerInit = { port: 43134, host: 'localhost' }, createFactory: CreateFactory) {
constructor (options: ServerInit = { port: 43134, host: 'localhost' }, factory: Factory) {
this.options = options
this.server = null
this.port = this.options.port ?? 43134
this.host = this.options.host ?? 'localhost'
this.createFactory = createFactory
this.ipfsd = factory
this.nodes = {}
}

/**
Expand All @@ -42,7 +40,7 @@ class Server {
}
})

routes(this.server, this.createFactory)
routes(this.server, this.ipfsd, this.nodes)

await this.server.start()

Expand All @@ -56,6 +54,21 @@ class Server {
if (this.server != null) {
await this.server.stop(options)
}

await this.clean()
}

/**
* Stop any nodes created by this server
*/
async clean (): Promise<void> {
await this.ipfsd.clean()

// remove references to nodes
for (const key of Object.getOwnPropertyNames(this.nodes)) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.nodes[key]
}
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,5 @@ export const createServer = (options?: number | { port: number }, factoryOptions
return new Server({
port,
host: '127.0.0.1'
}, () => {
return createFactory(factoryOptions, factoryOverrides)
})
}, createFactory(factoryOptions, factoryOverrides))
}
66 changes: 66 additions & 0 deletions test/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,70 @@ describe('`createServer`', () => {
})
await node.stop()
})

it('should clean server', async () => {
if (!isNode && !isElectronMain) {
return
}

server = createServer(33333, {
type: 'kubo',
test: true,
disposable: false,
rpc: createKuboRPCClient,
bin: isNode ? kubo.path() : undefined
})
await server.start()

const factory = createFactory({
endpoint: `http://127.0.0.1:${server.port}`
})

const node = await factory.spawn({
type: 'kubo',
remote: true,
rpc: createKuboRPCClient
})

await expect(node.api.isOnline()).to.eventually.be.true()
expect(Object.keys(server.nodes)).to.have.lengthOf(1)

await server.clean()

await expect(node.api.isOnline()).to.eventually.be.false()
expect(Object.keys(server.nodes)).to.have.lengthOf(0)
})

it('should clean server on stop', async () => {
if (!isNode && !isElectronMain) {
return
}

server = createServer(44444, {
type: 'kubo',
test: true,
disposable: false,
rpc: createKuboRPCClient,
bin: isNode ? kubo.path() : undefined
})
await server.start()

const factory = createFactory({
endpoint: `http://127.0.0.1:${server.port}`
})

const node = await factory.spawn({
type: 'kubo',
remote: true,
rpc: createKuboRPCClient
})

await expect(node.api.isOnline()).to.eventually.be.true()
expect(Object.keys(server.nodes)).to.have.lengthOf(1)

await server.stop()

await expect(node.api.isOnline()).to.eventually.be.false()
expect(Object.keys(server.nodes)).to.have.lengthOf(0)
})
})
12 changes: 5 additions & 7 deletions test/endpoint/routes.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ describe('routes', function () {

before(async () => {
server = new Hapi.Server({ port: 43134 })
routes(server, async () => {
return createFactory({
type: 'kubo',
rpc: createKuboRPCClient,
bin: isNode ? kubo.path() : undefined
})
})
routes(server, createFactory({
type: 'kubo',
rpc: createKuboRPCClient,
bin: isNode ? kubo.path() : undefined
}), {})
})

after(async () => {
Expand Down

0 comments on commit 855bec9

Please sign in to comment.