Skip to content

Commit

Permalink
Merge pull request #786 from oceanprotocol/issue-768-env-cpu-mem
Browse files Browse the repository at this point in the history
Compute Job - Check container stats, regarding cpu & mem usage
  • Loading branch information
paulo-ocean authored Dec 16, 2024
2 parents 83d01f8 + 5651337 commit ddfc8a5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
12 changes: 12 additions & 0 deletions src/components/c2d/compute_engine_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ export abstract class C2DEngine {
public getStreamableLogs(jobId: string): Promise<NodeJS.ReadableStream> {
throw new Error(`Not implemented for this engine type`)
}

protected async getJobEnvironment(job: DBComputeJob): Promise<ComputeEnvironment> {
const environments: ComputeEnvironment[] = await (
await this.getComputeEnvironments()
).filter((env: ComputeEnvironment) => env.id === job.environment)
// found it
if (environments.length === 1) {
const environment = environments[0]
return environment
}
return null
}
}

export class C2DEngineLocal extends C2DEngine {
Expand Down
23 changes: 19 additions & 4 deletions src/components/c2d/compute_engine_docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import type {
ComputeResult,
DockerPlatform
} from '../../@types/C2D/C2D.js'
// import { getProviderFeeToken } from '../../components/core/utils/feesHandler.js'
import { getConfiguration } from '../../utils/config.js'
import { C2DEngine } from './compute_engine_base.js'
import { C2DDatabase } from '../database/C2DDatabase.js'
import { create256Hash } from '../../utils/crypt.js'
import { Storage } from '../storage/index.js'
import Dockerode from 'dockerode'
import type { ContainerCreateOptions, VolumeCreateOptions } from 'dockerode'
import type { ContainerCreateOptions, HostConfig, VolumeCreateOptions } from 'dockerode'
import * as tar from 'tar'
import {
createWriteStream,
Expand All @@ -41,6 +40,7 @@ import { Service } from '../../@types/DDO/Service.js'
import { decryptFilesObject, omitDBComputeFieldsFromComputeJob } from './index.js'
import * as drc from 'docker-registry-client'
import { ValidateParams } from '../httpRoutes/validateCommands.js'
import { convertGigabytesToBytes } from '../../utils/util.js'

export class C2DEngineDocker extends C2DEngine {
private envs: ComputeEnvironment[] = []
Expand Down Expand Up @@ -202,7 +202,7 @@ export class C2DEngineDocker extends C2DEngine {

const jobId = generateUniqueID()

// TO DO C2D - Check image, check arhitecture, etc
// C2D - Check image, check arhitecture, etc
const image = getAlgorithmImage(algorithm)
// ex: node@sha256:1155995dda741e93afe4b1c6ced2d01734a6ec69865cc0997daf1f4db7259a36
if (!image) {
Expand All @@ -219,6 +219,7 @@ export class C2DEngineDocker extends C2DEngine {
envIdWithHash ? environment : null,
environment
)

const validation = await C2DEngineDocker.checkDockerImage(image, env.platform)
if (!validation.valid)
throw new Error(`Unable to validate docker image ${image}: ${validation.reason}`)
Expand Down Expand Up @@ -498,9 +499,11 @@ export class C2DEngineDocker extends C2DEngine {
await this.db.updateJob(job)
await this.cleanupJob(job)
}
// get env info
const environment = await this.getJobEnvironment(job)
// create the container
const mountVols: any = { '/data': {} }
const hostConfig: any = {
const hostConfig: HostConfig = {
Mounts: [
{
Type: 'volume',
Expand All @@ -510,6 +513,18 @@ export class C2DEngineDocker extends C2DEngine {
}
]
}
if (environment != null) {
// limit container CPU & Memory usage according to env specs
hostConfig.CpuCount = environment.cpuNumber || 1
// if more than 1 CPU
if (hostConfig.CpuCount > 1) {
hostConfig.CpusetCpus = `0-${hostConfig.CpuCount - 1}`
}
hostConfig.Memory = 0 || convertGigabytesToBytes(environment.ramGB)
// set swap to same memory value means no swap (otherwise it use like 2X mem)
hostConfig.MemorySwap = hostConfig.Memory
}
// console.log('host config: ', hostConfig)
const containerInfo: ContainerCreateOptions = {
name: job.jobId + '-algoritm',
Image: job.containerImage,
Expand Down
10 changes: 10 additions & 0 deletions src/utils/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,13 @@ export function deleteKeysFromObject(source: any, keys: string[]): any {
})
return source
}

export function convertGigabytesToBytes(gigabytes: number): number {
if (gigabytes < 0) {
throw new Error('Input must be a non-negative number')
}

const bytesInAGigabyte = 1024 ** 3 // 1 gigabyte = 1024^3 bytes
const bytes = gigabytes * bytesInAGigabyte
return bytes
}

0 comments on commit ddfc8a5

Please sign in to comment.