El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.
En nuestro anterior post a) Adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en todos los ámbitos de la vida, incluida la educación; debatimos cómo podemos usar EasyNMT para traducir nuestra .md archivos en diferentes idiomas. También hemos discutido cómo podemos hacer frente a esta funcionalidad al usuario a través de agregar un dropdown al editor de marcación. En este post nosotrosM SK2 vamos a discutir cómo podemos usar un servicio de fondo para gestionar las tareas de traducción .
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. a) Adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en todos los ámbitos de la vida, incluida la educación;.
El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la protección de los derechos humanos y las libertades fundamentales, incluidos los derechos económicos, sociales y culturales.
La primera cosa que debemos hacer es establecer un contenedor de docker para ejecutar nuestro servicio de traducción. Nosotros' utilizaremos el EasyNMT image de docker que está disponible en Docker Hub.
easynmt:
image: easynmt/api:2.0.2-cpu
volumes:
- /mnt/easynmt:/cache/
deploy:
resources:
limits:
cpus: "4.0"
networks:
- app_network
Aquí estamos creando un servicio llamado easynmt El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. easynmt/api:2.0.2-cpu image. También estamos montando un volumen para almacenar el archivo de traducción. También se están fijando límites de recursos para asegurar que el servicio no consume todos los recursos en la máquina host M SK3EasyNMT es un poco de ganado de recursosMSC4
El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.
Un problema es que EasyNMT puede tomar un poco para empezar y/o descender aleatoriamenteM SK1 Así que en nuestro El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. Necesitamos manejar esto.
El Presidente interino (habla en inglés): Doy las gracias al representante de la República Islámica del Irán por su declaración.
Cuando iniciamos el servicio tenemos que comprobar si está funcionando el servicio EasyNMT. Si no es' no congelaremos el procesamiento futuro hasta que sea . También tenemos que manejar el caso en el que el servicio se desgaste MSC3como puede ser aisladoM SK4
private async Task<bool> StartupHealthCheck(CancellationToken cancellationToken)
{
var count = 1;
var isUp = false;
while (true)
{
if (await Ping(cancellationToken))
{
logger.LogInformation("Translation service is available");
isUp = true;
break;
}
await Task.Delay(10000, cancellationToken);
count++;
if (count > 3)
{
logger.LogError("Translation service is not available trying again (count: {Count})", count);
_translations.Writer.Complete();
await cancellationTokenSource.CancelAsync();
isUp = false;
break;
}
}
return isUp;
}
private async Task PeriodicHealthCheck(CancellationToken cancellationToken)
{
// Run the health check periodically (e.g., every 60 seconds)
const int delayMilliseconds = 60000;
while (!cancellationToken.IsCancellationRequested)
{
try
{
if (!await Ping(cancellationToken))
{
logger.LogError("Translation service is not available");
await cancellationTokenSource.CancelAsync();
_translations.Writer.Complete();
TranslationServiceUp = false;
}
else
{
logger.LogInformation("Translation service is healthy");
TranslationServiceUp = true;
}
}
catch (Exception ex)
{
TranslationServiceUp = false;
logger.LogError(ex, "Error during service health check");
await cancellationTokenSource.CancelAsync();
_translations.Writer.Complete();
}
// Wait before checking again
await Task.Delay(delayMilliseconds, cancellationToken);
}
}
public async Task<bool> Ping(CancellationToken cancellationToken)
{
if (!await markdownTranslatorService.IsServiceUp(cancellationToken))
{
logger.LogError("Translation service is not available");
return false;
}
return true;
}
Esto se debe principalmente a que EasyNMT carece de un punto final de control de salud.
private string[] IPs = translateServiceConfig.IPs;
public async ValueTask<bool> IsServiceUp(CancellationToken cancellationToken)
{
var workingIPs = new List<string>();
try
{
foreach (var ip in IPs)
{
logger.LogInformation("Checking service status at {IP}", ip);
var response = await client.GetAsync($"{ip}/model_name", cancellationToken);
if (response.IsSuccessStatusCode)
{
workingIPs.Add(ip);
}
}
IPs = workingIPs.ToArray();
if (!IPs.Any()) return false;
return true;
}
catch (Exception e)
{
logger.LogError(e, "Error checking service status");
return false;
}
}
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. IsServiceUp method we ping todos los servicios EasyNMT disponibles para ver si están por encima. Si alguno de ellos es regresar true Si no, regresaremos. false. También actualizamos la lista de IPs de servicio para incluir sólo aquellos que están en órbita.
El Grupo de Trabajo tal vez desee tomar nota del informe del Secretario General sobre la aplicación de las recomendaciones contenidas en el párrafo 6 supra.
En la API ahora verificamos si el servicio está disponible antes de desactivar una solicitud de traducción:
[HttpPost("start-translation")]
[ValidateAntiForgeryToken]
public async Task<Results<Ok<string>, BadRequest<string>>> StartTranslation([FromBody] MarkdownTranslationModel model)
{
if(!backgroundTranslateService.TranslationServiceUp)
{
return TypedResults.BadRequest("Translation service is down");
}
// Create a unique identifier for this translation task
var taskId = Guid.NewGuid().ToString("N");
var userId = Request.GetUserId(Response);
// Trigger translation and store the associated task
var translationTask = await backgroundTranslateService.Translate(model);
var translateTask = new TranslateTask(taskId, model.Language, translationTask);
translateCacheService.AddTask(userId, translateTask);
// Return the task ID to the client
return TypedResults.Ok(taskId);
}
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.
Ahora hemos cambiado para usar Channels para nuestra lista de traducciones; es' sólo una versión mejor del BufferBlock utilizamos anteriormente (performencia mejor, menor memoria etcM SK2
private readonly
Channel<(PageTranslationModel, TaskCompletionSource<TaskCompletion>)>
_translations = Channel.CreateUnbounded<(PageTranslationModel, TaskCompletionSource<TaskCompletion>)>();
public async Task<Task<TaskCompletion>> Translate(MarkdownTranslationModel message)
{
// Create a TaskCompletionSource that will eventually hold the result of the translation
var translateMessage = new PageTranslationModel
{
Language = message.Language,
OriginalFileName = "",
OriginalMarkdown = message.OriginalMarkdown,
Persist = false
};
return await Translate(translateMessage);
}
private async Task<Task<TaskCompletion>> Translate(PageTranslationModel message)
{
// Create a TaskCompletionSource that will eventually hold the result of the translation
var tcs = new TaskCompletionSource<TaskCompletion>();
// Send the translation request along with the TaskCompletionSource to be processed
await _translations.Writer.WriteAsync((message, tcs));
return tcs.Task;
}
Se puede ver que esto utiliza un TaskCompletionSource para mantener el resultado de la traducción. Luego envíamos la solicitud de traducción junto con el TaskCompletionSource El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. await _translations.Writer.WriteAsync((message, tcs)); El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. TaskCompletion Tasa a la API que permite que se cache.
El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.
El principal 'loop' dentro de nuestro IHostedService es responsable del procesamiento de todas las solicitudes de traducción que entran en el diagrama.
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.
graph TD
A[Start TranslateFilesAsync Method] --> B[Create empty processingTasks list]
B --> C{!cancellationToken.IsCancellationRequested}
C -->|True| D[Check if processingTasks.Count < markdownTranslatorService.IPCount]
D -->|True| E[Read item from _translations.Reader]
E --> F[Get translateModel and tcs from item]
F --> G[Create task using TranslateTask method]
G --> H[Add task to processingTasks list]
H --> D
D -->|False| I[Wait for any task to complete using Task.WhenAny]
I --> J[Remove completed task from processingTasks]
J --> K[Handle result of completed task]
K --> L[Await completedTask]
L --> M{Exception in task?}
M -->|Yes| N[Log error using logger.LogError]
M -->|No| O[Continue processing]
O --> C
C -->|False| P[Catch OperationCanceledException]
P --> Q[Log cancellation using logger.LogError]
C -->|False| R[Catch general Exception]
R --> S[Log exception using logger.LogError]
S --> T[End TranslateFilesAsync Method]
Q --> T
Para racionalizar las traducciones creemos un circuito que sólo trata de procesar tantas traducciones a la vez como tenemos servicios EasyNMT en marcha. Esto es para evitar que el servicio se convierta en un superfluo.
Para cada uno de estos nosotros luego rodamos una nueva Tasa de Traducción
TranslateTask(cancellationToken, translateModel, item, tcs);
A continuación, utilizamos Task.WhenAny para esperar que cualquiera de las tareas se complete. Luego retiramos la tarea completada de la lista y tratamos el resultado de la misión completada. Si hay una excepción, lo logamos y continuamos con el procesamientoM SK2
Luego reiniciamos el circuito hasta que el servicio se cancele.
private async Task TranslateFilesAsync(CancellationToken cancellationToken)
{
try
{
var processingTasks = new List<Task>();
while (!cancellationToken.IsCancellationRequested)
{
while (processingTasks.Count < markdownTranslatorService.IPCount &&
!cancellationToken.IsCancellationRequested)
{
var item = await _translations.Reader.ReadAsync(cancellationToken);
var translateModel = item.Item1;
var tcs = item.Item2;
// Start the task and add it to the list
var task = TranslateTask(cancellationToken, translateModel, item, tcs);
processingTasks.Add(task);
}
// Wait for any of the tasks to complete
var completedTask = await Task.WhenAny(processingTasks);
// Remove the completed task
processingTasks.Remove(completedTask);
// Optionally handle the result of the completedTask here
try
{
await completedTask; // Catch exceptions if needed
}
catch (Exception ex)
{
logger.LogError(ex, "Error translating markdown");
}
}
}
catch (OperationCanceledException)
{
logger.LogError("Translation service was cancelled");
}
catch (Exception e)
{
logger.LogError(e, "Error translating markdown");
}
}
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.
El 'meatM SK1 de este procesamiento se maneja en TranslateTask (Uso esto para traducir archivos y en el futuro para guardar artículos traducidos de nuevo al DB).
En primer lugar, veo si la entrada original ha cambiado;aunque utilizo un hash de archivo del contenido original / simplemente veo la fecha actualizada de la entrada del blog en comparación con las traducidasM SK2 Si no se ha modificado ' no lo he modificado, salgo de la traducciónMSC4 Si se ha alterado, traduco el marcaje y lo mantengo si es necesarioMNK5
Luego acudo al método principal de traducción del MarkdownTranslatorService para hacer la traducción.
Vea cómo lo doy. a) Adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en todos los ámbitos de la vida, incluida la educación;.
Esto devolve la marcada traducida que entonces persisto si es necesario.
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. tcs Resulta en la marcada traducida y la configura como completa.
private async Task TranslateTask(CancellationToken cancellationToken, PageTranslationModel translateModel,
(PageTranslationModel, TaskCompletionSource<TaskCompletion>) item,
TaskCompletionSource<TaskCompletion> tcs)
{
var scope = scopeFactory.CreateScope();
var slug = Path.GetFileNameWithoutExtension(translateModel.OriginalFileName);
if (translateModel.Persist)
{
if (await EntryChanged(scope, slug, translateModel))
{
logger.LogInformation("Entry {Slug} has changed, translating", slug);
}
else
{
logger.LogInformation("Entry {Slug} has not changed, skipping translation", slug);
tcs.SetResult(new TaskCompletion(null, translateModel.Language, true, DateTime.Now));
return;
}
}
logger.LogInformation("Translating {File} to {Language}", translateModel.OriginalFileName,
translateModel.Language);
try
{
var translatedMarkdown =
await markdownTranslatorService.TranslateMarkdown(translateModel.OriginalMarkdown,
translateModel.Language, cancellationToken);
if (item.Item1.Persist)
{
await PersistTranslation(scope, slug, translateModel, translatedMarkdown);
}
tcs.SetResult(new TaskCompletion(translatedMarkdown, translateModel.Language, true, DateTime.Now));
}
catch (Exception e)
{
logger.LogError(e, "Error translating {File} to {Language}", translateModel.OriginalFileName,
translateModel.Language);
tcs.SetException(e);
}
}
El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.
Así que 's es esto , esta es la forma de manejar las traducciones de fondo en mi blog . yo ' he estado usando esto durante un mes o así ahora y M' está funcionando bien m. Aunque en realidad parece asombroso el código es bastante directo МSK6 Espero que esto te ayude en tus propios proyectos .