Refactor FaceAI build process and update Docker configurations to include matcher binary
This commit is contained in:
parent
b13c306883
commit
d36b0f4e46
15 changed files with 177 additions and 30 deletions
|
|
@ -117,7 +117,10 @@ const emit = defineEmits([
|
|||
|
||||
<div class="faceai-dropzone-inner">
|
||||
<div class="faceai-dropzone-icon">
|
||||
<i class="fa fa-cloud-upload" aria-hidden="true"></i>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
||||
<path d="M12.75 3.75a.75.75 0 0 0-1.5 0v8.69L8.78 9.97a.75.75 0 1 0-1.06 1.06l3.75 3.75a.75.75 0 0 0 1.06 0l3.75-3.75a.75.75 0 1 0-1.06-1.06l-2.47 2.47V3.75Z" fill="currentColor" />
|
||||
<path d="M5.25 15a3 3 0 0 0 .28 6h12.94a3.53 3.53 0 0 0 .27-7.04 5.75 5.75 0 0 0-11.17-1.48A3.75 3.75 0 0 0 5.25 15Zm1.5 0c0-.87.35-1.65.92-2.22a.75.75 0 0 0 .18-.77 4.25 4.25 0 0 1 8.29 1.39v.25a.75.75 0 0 0 .75.75h1.58a2.03 2.03 0 0 1 0 4.06H5.53A1.5 1.5 0 1 1 5.53 15h1.22Z" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<template v-if="selectedFile">
|
||||
|
|
@ -290,6 +293,11 @@ const emit = defineEmits([
|
|||
box-shadow: inset 0 0 0 1px rgba(191, 158, 117, 0.24);
|
||||
}
|
||||
|
||||
.faceai-dropzone-icon svg {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.faceai-dropzone-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,12 @@ function closeMenu() {
|
|||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#" @click="closeMenu">
|
||||
<i class="fa fa-user" aria-hidden="true"></i> Il mio account
|
||||
<span class="faceai-inline-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" focusable="false">
|
||||
<path d="M12 12.5a4.25 4.25 0 1 0 0-8.5 4.25 4.25 0 0 0 0 8.5Zm0 2.25c-4.48 0-8.25 2.18-8.25 4.75 0 .28.22.5.5.5h15.5a.5.5 0 0 0 .5-.5c0-2.57-3.77-4.75-8.25-4.75Z" fill="currentColor" />
|
||||
</svg>
|
||||
</span>
|
||||
Il mio account
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
|
|
@ -78,3 +83,18 @@ function closeMenu() {
|
|||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.faceai-inline-icon {
|
||||
display: inline-flex;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
margin-right: 0.35rem;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.faceai-inline-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ export function legacyAsset(path) {
|
|||
export function injectLegacyStylesheets() {
|
||||
const stylesheets = [
|
||||
legacyAsset('/vendor/bootstrap/css/bootstrap.min.css'),
|
||||
legacyAsset('/css/font-awesome.min.css'),
|
||||
'https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i',
|
||||
legacyAsset('/css/custom-style.css')
|
||||
];
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ export async function runFaceMatcher({ matcherBinary, selfiePath, pklPath, csvPa
|
|||
|
||||
child.on('error', (error) => {
|
||||
clearTimeout(timer);
|
||||
if (error?.code === 'ENOENT') {
|
||||
reject(new Error(`face_matcher not found at ${matcherBinary}. Check FACEAI_MATCHER_BINARY and the processor bind mount.`));
|
||||
return;
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { constants as fsConstants } from 'node:fs';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { Worker } from 'bullmq';
|
||||
|
|
@ -15,6 +16,22 @@ import { parseMatcherCsv, resolvePklPath, runFaceMatcher } from './worker-utils.
|
|||
|
||||
const connection = createRedisConnection(config.redisUrl);
|
||||
|
||||
async function ensureMatcherBinaryAvailable() {
|
||||
try {
|
||||
await fs.access(config.matcherBinary, fsConstants.X_OK);
|
||||
} catch (error) {
|
||||
console.error(`FaceAI processor cannot start because the matcher binary is unavailable: ${config.matcherBinary}`);
|
||||
console.error('Ensure FACEAI_MATCHER_BINARY points to a real executable and that the processor bind mount contains face_matcher.');
|
||||
if (error?.code === 'ENOENT') {
|
||||
console.error('The configured matcher path does not exist inside the processor runtime.');
|
||||
} else if (error?.code === 'EACCES') {
|
||||
console.error('The configured matcher path exists but is not executable by the processor runtime.');
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function formatLogLine(message, details) {
|
||||
const timestamp = new Date().toISOString();
|
||||
if (details === undefined) {
|
||||
|
|
@ -147,6 +164,8 @@ async function processJob(job) {
|
|||
}
|
||||
}
|
||||
|
||||
await ensureMatcherBinaryAvailable();
|
||||
|
||||
const worker = new Worker(config.queueName, processJob, {
|
||||
connection,
|
||||
concurrency: config.workerConcurrency
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue