コード例 #1
0
ファイル: Translator.cs プロジェクト: osCore2/translator
        /**
         * @brief One of these in the whole process.
         *        It takes pending translations from translationq,
         *        translates the message, saves the translation,
         *        then calls all the Finished events.
         *        The translation remains in the translations
         *        dictionary in case the translation is needed
         *        again.
         */
        private static void TranslatorThread()
        {
            Monitor.Enter(queuelock);

            try {
                while (runthread)
                {
                    Watchdog.UpdateThread();

                    // take old translations out of cache
                    DateTime utcnow = DateTime.UtcNow;
                    LinkedListNode <Translation> lln;
                    Translation val;
                    while ((lln = oldtranslations.First) != null)
                    {
                        val = lln.Value;
                        if (val.xlation == null)
                        {
                            break;
                        }
                        if ((numcachedchars < CACHE_CHARS) &&
                            (utcnow.Subtract(val.lastuse).TotalSeconds < CACHE_SECS))
                        {
                            break;
                        }
                        numcachedchars -= val.key.Length;
                        oldtranslations.Remove(lln);
                        translations.Remove(val.key);
                    }

                    // wait for something to process and dequeue it
                    if (translationq.Count == 0)
                    {
                        Monitor.Wait(queuelock, WD_TIMEOUT_MS / 2);
                        continue;
                    }
                    val = translationq.Dequeue();

                    // do the translation (might take a few seconds)
                    string incorig, xlation;
                    Monitor.Exit(queuelock);
                    try {
                        try {
                            xlation = service.Translate(val.agentID, val.srclc, val.dstlc, val.original);
                            if (xlation == null)
                            {
                                throw new ApplicationException("result null");
                            }
                            xlation = xlation.Trim();
                            if (xlation == "")
                            {
                                throw new ApplicationException("result empty");
                            }
                        } catch (Exception e) {
                            m_log.Warn("[Translator]: failed " + val.srclc + " -> " + val.dstlc + ": ", e);
                            m_log.Info("[Translator]: original=<" + val.original + ">");
                            xlation = null;
                        }

                        // original text with language code if translation failed
                        incorig = "[[[" + val.srclc + "]]]" + val.original;
                        if (xlation == null)
                        {
                            xlation = incorig;
                        }
                        else
                        {
                            incorig = xlation + "\n" + incorig;
                        }
                    } finally {
                        Monitor.Enter(queuelock);
                    }

                    // mark entry in translations dictionary as completed
                    val.xlation = xlation;
                    val.agentID = null;

                    // see if anything was waiting for the translation to complete
                    // if so, clear out the list and call them whilst unlocked
                    TranslatorFinished tfs = val.onFinished;
                    if (tfs != null)
                    {
                        val.onFinished = null;
                        Monitor.Exit(queuelock);
                        try {
                            do
                            {
                                tfs.finished(tfs.showorig ? incorig : xlation);
                                tfs = tfs.nextfin;
                            } while (tfs != null);
                        } finally {
                            Monitor.Enter(queuelock);
                        }
                    }
                }
            } catch (Exception e) {
                m_log.Error("[Translator]: Error in translator thread", e);
            } finally {
                runthread = false;
                Monitor.Exit(queuelock);
                Watchdog.RemoveThread(true);
            }
        }
コード例 #2
0
ファイル: Translator.cs プロジェクト: osCore2/translator
        /**
         * @brief Start translating the message, call finished when done.
         */
        private static void Translate(string srclc, string dstlc, bool showorig, string message, string agentID, ITranslatorFinished finished)
        {
            message = message.Trim();

            // key for the translations dictionary
            string key = srclc + ":" + dstlc + ":" + message;

            string xlation = null;

            lock (queuelock) {
                if (runthread)
                {
                    // see if we already have this translation either done or in progress
                    Translation val;
                    if (translations.TryGetValue(key, out val))
                    {
                        oldtranslations.Remove(val.uselink);
                    }
                    else
                    {
                        // no, queue the translation for processing
                        val               = new Translation();
                        val.agentID       = agentID;
                        val.key           = key;
                        translations[key] = val;
                        translationq.Enqueue(val);
                        numcachedchars += key.Length;
                        Monitor.PulseAll(queuelock);
                    }

                    // make it the newest translation around
                    val.lastuse = DateTime.UtcNow;
                    oldtranslations.AddLast(val.uselink);

                    // if translation in progress, queue 'finished' for processing when done
                    xlation = val.xlation;
                    if (xlation == null)
                    {
                        TranslatorFinished tf = new TranslatorFinished();
                        tf.nextfin     = val.onFinished;
                        tf.finished    = finished;
                        tf.showorig    = showorig;
                        val.onFinished = tf;
                    }
                }
                else
                {
                    // translation thread not running (crashed or whatever)
                    xlation  = "[[[" + srclc + "]]]" + message;
                    showorig = false;
                }
            }

            // if translation completed, call finished right now
            if (xlation != null)
            {
                if (showorig)
                {
                    xlation += "\n[[[" + srclc + "]]]" + message;
                }
                finished(xlation);
            }
        }