Advertisement
Guest User

Untitled

a guest
Jan 24th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.98 KB | None | 0 0
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Newtonsoft.Json;
  7. using SchoolInfoApp.Domain;
  8. using SchoolInfoApp.Domain.Models;
  9. using SchoolInfoApp.Framework.Translation;
  10. using SchoolInfoApp.Infrastructure.NHibernate.Interface;
  11. using SIA.BL.Modules.Translation.Commands;
  12. using SIA.Core;
  13. using SIA.Core.Cqrs.Interface;
  14. using SIA.Core.Translation;
  15. using SIA.Core.Utilities.Extensions;
  16.  
  17. namespace SIA.API.Services.Translation
  18. {
  19.     public class TranslationExecutor : ITranslationExecutor
  20.     {
  21.         private readonly ILogService _logService;
  22.         private readonly ISessionSource _sessionSource;
  23.         private readonly ICommandDispatcher _commandDispatcher;
  24.         private readonly IGoogleTranslateService _googleTranslateService;
  25.         private readonly IGoogleTranslationRepository _googleTranslationRepository;
  26.  
  27.         private const int WaitThreshold = 200; //ms
  28.        
  29.         private readonly object _taskLock = new object();
  30.         private readonly object _saveCacheLock = new object();
  31.         private readonly ConcurrentQueue<TranslationTextRequest> _pendingTranslations = new ConcurrentQueue<TranslationTextRequest>();
  32.         private Task<Dictionary<string, IDictionary<string, string>>> _translationTask;
  33.  
  34.         public TranslationExecutor(
  35.             ILogService logService,
  36.             ISessionSource sessionSource,
  37.             ICommandDispatcher commandDispatcher,
  38.             IGoogleTranslateService googleTranslateService,
  39.             IGoogleTranslationRepository googleTranslationRepository)
  40.         {
  41.             _logService = logService;
  42.             _sessionSource = sessionSource;
  43.             _commandDispatcher = commandDispatcher;
  44.             _googleTranslateService = googleTranslateService;
  45.             _googleTranslationRepository = googleTranslationRepository;
  46.         }
  47.  
  48.         public IDictionary<string, string> GetTranslations(OrgTranslationRequest request)
  49.         {
  50.             _logService.Info("Translation Executor called");
  51.             var trans = request.TextsToTranslate.Select(x => new TranslationTextRequest(request.Language, x));
  52.             foreach (var tran in trans)
  53.             {
  54.                 _pendingTranslations.Enqueue(tran);
  55.             }
  56.             lock (_taskLock)
  57.             {
  58.                     StartTranslationTask();
  59.             }
  60.             IDictionary<string, IDictionary<string, string>> allTranslationsDictionary = null;
  61.             _translationTask.ContinueWith(x =>
  62.             {
  63.                     allTranslationsDictionary = x.Result;
  64.                     _logService.Info("Translation ended. Result: " + JsonConvert.SerializeObject(allTranslationsDictionary));
  65.                     lock (_taskLock)
  66.                     {
  67.                             ClearTranslationTask();
  68.                     }
  69.  
  70.             }).Wait();
  71.             var requestedTranslations = request.TextsToTranslate.ToDictionary(x => x, x => x);
  72.             var allTranslationKeys = requestedTranslations.Keys.ToArray();
  73.             if (allTranslationsDictionary == null)
  74.             {
  75.                 return requestedTranslations;
  76.             }
  77.             if (allTranslationsDictionary.ContainsKey(request.Language))
  78.             {
  79.                 var translations = allTranslationsDictionary[request.Language];
  80.                 var count = 0;
  81.                 var caches = new HashSet<GoogleTranslationCache>();
  82.                 foreach (var key in allTranslationKeys)
  83.                 {
  84.                     if (translations.ContainsKey(key))
  85.                     {
  86.                         var translation = translations[key];
  87.                         requestedTranslations[key] = translation;
  88.                         count += translation.Length;
  89.                         caches.Add(new GoogleTranslationCache
  90.                         {
  91.                             Id = Guid.NewGuid(),
  92.                             Hash = key.GetSha1Hash(),
  93.                             Language = request.Language,
  94.                             Translation = translation
  95.                         });
  96.                     }
  97.                 }
  98.                 SaveTranslationCaches(caches);
  99.                 if (count > 0)
  100.                 {
  101.                     LogCharacterCount(request.OrgId, request.Language, count);
  102.                 }
  103.             }
  104.             _logService.Info("Done: requestedTranslations: " + JsonConvert.SerializeObject(requestedTranslations));
  105.             return requestedTranslations;
  106.         }
  107.  
  108.         private void ClearTranslationTask()
  109.         {
  110.             _translationTask = null;
  111.         }
  112.  
  113.         private void StartTranslationTask()
  114.         {
  115.             if (_translationTask != null) return;
  116.                
  117.             _translationTask = Task.Run(() =>
  118.             {
  119.                 var allTranslationsDictionary = new Dictionary<string, IDictionary<string, string>>();
  120.                 var translationsDictionary = new Dictionary<string, HashSet<string>>();
  121.                 TranslationTextRequest request;
  122.                 while (_pendingTranslations.TryDequeue(out request))
  123.                 {
  124.                     _logService.Info("Dequeue request: " + _pendingTranslations.Count);
  125.                     if (!translationsDictionary.ContainsKey(request.Language))
  126.                     {
  127.                         translationsDictionary.Add(request.Language, new HashSet<string>());
  128.                     }
  129.                     translationsDictionary[request.Language].Add(request.TextToTranslate);
  130.                     if (_pendingTranslations.Count == 0)
  131.                     {
  132.                         _logService.Info($"Queue is empty. Waitnig for {WaitThreshold}ms for more incoming requests");
  133.                         Task.Delay(WaitThreshold).Wait();
  134.                     }
  135.                 }
  136.                 foreach (var language in translationsDictionary.Keys)
  137.                 {
  138.                     var sourceTexts = translationsDictionary[language].ToArray();
  139.                     var translations = sourceTexts.ToDictionary(x => x, x => x);
  140.                     string[] googleTranslations;
  141.                     try
  142.                     {
  143.                         _logService.Info("Calling Google Translate API");
  144.                         googleTranslations = _googleTranslateService.GetTranslations(sourceTexts, language);
  145.                     }
  146.                     catch (Exception e)
  147.                     {
  148.                         _logService.Error("Error during calling Google Translator Service: " + e);
  149.                         continue;
  150.                     }
  151.                     for (var i = 0; i < googleTranslations.Length; i++)
  152.                     {
  153.                         var original = sourceTexts[i];
  154.                         var translation = googleTranslations[i];
  155.                         translations[original] = translation;
  156.                     }
  157.                     allTranslationsDictionary.Add(language, translations);
  158.                 }
  159.                 return allTranslationsDictionary;
  160.             });
  161.         }
  162.  
  163.         private void LogCharacterCount(int orgId, string language, int count)
  164.         {
  165.             var org = _sessionSource.GetContextualSession().Load<Organization>(orgId);
  166.             using (var session = _sessionSource.CreateStatelessSession())
  167.             {
  168.                 session.SetBatchSize(1000);
  169.                 using (var tran = session.BeginTransaction())
  170.                 {
  171.                     var charCount = new GoogleTranslationCharacterCount
  172.                     {
  173.                         Organization = org,
  174.                         CharacterCount = count,
  175.                         CreatedAt = SystemTime.Now(),
  176.                         LanguageCode = language
  177.                     };
  178.                     session.Insert(charCount);
  179.                     tran.Commit();
  180.                 }
  181.             }
  182.         }
  183.  
  184.         private void SaveTranslationCaches(ICollection<GoogleTranslationCache> caches)
  185.         {
  186.             lock (_saveCacheLock)
  187.             {
  188.                 var unsavedCaches = caches.Where(x => !_googleTranslationRepository.ContainsItemInCache(x.Hash, x.Language)).ToList();
  189.                 _commandDispatcher.Dispatch(new BulkInsertGoogleTranslationCaches(unsavedCaches));
  190.                 _googleTranslationRepository.AddItems(caches, false);
  191.             }
  192.         }
  193.  
  194.         private void SaveTranslationCache(string language, string original, string translation)
  195.         {
  196.             lock (_saveCacheLock)
  197.             {
  198.                 var hash = original.GetSha1Hash();
  199.                 if (_googleTranslationRepository.ContainsItemInCache(hash, language)) return;
  200.                 var translationCache = new GoogleTranslationCache
  201.                 {
  202.                     Id = Guid.NewGuid(),
  203.                     Language = language,
  204.                     Hash = hash,
  205.                     Translation = translation
  206.                 };
  207.                 _googleTranslationRepository.AddTranslation(translationCache);
  208.             }
  209.         }
  210.     }
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement