2016-10-24 1 views
0

У меня есть приложение meteor, которое берет текст статьи и разбивает его на параграфы, предложения, слова и символы, а затем сохраняет это в json, который затем сохраняю как документ в коллекции. Документ, который я тестирую, теперь заканчивается как 15133 байта в mongodb.Что может заставить приложение метеора иногда создавать два документа?

Когда я вставляю документ, для его вставки требуется около 20 или 30 секунд. Затем иногда он снова запускается через мою процедуру создания статьи и вставляет другой документ. Иногда он заканчивается вставкой 3 или более документов. Иногда он ведет себя так, как должен, и вставляет только один документ в коллекцию.

Что я должен искать, что может вызвать такое поведение?

Вот мой код, в соответствии с просьбой:

Meteor.methods({ 
'createArticle': function (text, title) { 
    var article = {} 
    article.title = title 
    article.userID = "sdfgsdfg" 
    article.text = text 
    article.paragraphs = [] 
    var paragraphs = splitArticleIntoParagraphs(text) 
    console.log("paragraphs", paragraphs) 
    _.each(paragraphs, function (paragraph, p) { 
     if (paragraph !== "") { 
      console.log("paragraph", paragraph) 
      article.paragraphs[p] = {} 
      article.paragraphs[p].read = false 
      article.paragraphs[p].text = paragraph 
      console.log("paragraphs[p]", article.paragraphs[p]) 
      var sentences = splitParagraphIntoSentences(paragraph) 
      article.paragraphs[p].sentences = [] 
     } 
     _.each(sentences, function (sentence, s) { 
      if (sentence !== "") { 
       article.paragraphs[p].sentences[s] = {} 
       console.log("sentence", sentence) 
       article.paragraphs[p].sentences[s].text = sentence 
       article.paragraphs[p].sentences[s].read = false 
       console.log("paragraphs[p].sentences[s]", article.paragraphs[p].sentences[s]) 
       var wordsForward = splitSentenceIntoWordsForward(sentence) 
       console.log("wordsForward", JSON.stringify(wordsForward)) 
       article.paragraphs[p].sentences[s].forward = {} 
       article.paragraphs[p].sentences[s].forward.words = wordsForward 

       // var wordsReverse = splitSentenceIntoWordsReverse(sentence) 
       _.each(wordsForward, function (word, w) { 
        if (word) { 
         // console.log("word", JSON.stringify(word)) 
         // article.paragraphs[p].sentences[s] = {} 
         // article.paragraphs[p].sentences[s].forward = {} 
         // article.paragraphs[p].sentences[s].forward.words = [] 
         article.paragraphs[p].sentences[s].forward.words[w] = {} 
         article.paragraphs[p].sentences[s].forward.words[w].wordID = word._id 
         article.paragraphs[p].sentences[s].forward.words[w].simp = word.simp 
         article.paragraphs[p].sentences[s].forward.words[w].trad = word.trad 
         console.log("word.simp", word.simp) 
         var characters = word.simp.split('') 
         console.log("characters", characters) 
         article.paragraphs[p].sentences[s].forward.words[w].characters = [] 
         _.each(characters, function (character, c) { 
          if (character) { 
           console.log("character", character, p, s, w, c) 
           article.paragraphs[p].sentences[s].forward.words[w].characters[c] = {} 
           article.paragraphs[p].sentences[s].forward.words[w].characters[c].text = character 
           article.paragraphs[p].sentences[s].forward.words[w].characters[c].wordID = Words.findOne({simp: character})._id 
          } 
         }) 
        } 
       }) 
      } 
     }) 
    }) 
    // console.log("article", JSON.stringify(article)) 
    // console.log(JSON.stringify(article.paragraphs[10].sentences[1].forward))//.words[4].characters[0]) 
    console.log("done") 
    var id = Articles.insert(article) 
    console.log("id", id) 
    return id 
} 
}) 

я вызываю метод здесь:

Template.articleList.events({ 
"click #addArticle": function(event) { 
    event.preventDefault(); 
    var title = $('#title').val(); 
    var text = $('#text').val(); 
    $('#title').value = ''; 
    $('#text').value = ''; 
    $('#text').attr('rows', '3'); 
    Meteor.call('createArticle', text, title); 
} 
}) 
+0

отредактируйте свой вопрос и добавьте соответствующие коды. – Luna

+0

Можете ли вы проверить, ожидает ли он _.each() (все они) перед тем, как вставить статью? Вероятно, это преступник. Кроме того, добавьте, где вы вызываете метод на случай, если – Luna

+0

Добавлен вызов метода. Итак, вы говорите, что я должен вставить статью, а затем обновить ее, поскольку она проходит через _.each? Это занимает около 20-30 секунд после 'console.log (« done »)' – webmagnets

ответ

2

Важная вещь, чтобы иметь в виду, что методы метеора не работают очень хорошо, когда это для выполнения задач интенсивной работы с ЦП. Поскольку ваш метеоритный сервер работает только в одном потоке, любые блокирующие вычисления - например, ваши - будут влиять на все клиентские соединения, например. задержка сердечных сокращений DDP. Это, в свою очередь, может привести к тому, что клиенты будут думать, что соединение было отключено.

Как @ghybs, предложенный в одном из комментариев, ваш метод, вероятно, срабатывает несколько раз нетерпеливым клиентом DDP, который считает, что сервер отключен. Самый простой способ предотвратить такое поведение, добавляя noRetry флаг Meteor.apply, как описано здесь:

https://docs.meteor.com/api/methods.html#Meteor-apply

Meteor.call Я считаю, что не имеет такой опции.

Другая стратегия будет пытаться убедиться, что ваши методы являются идемпотентными, т. Е. Их вызов более одного раза не должны создавать никаких дополнительных эффектов. Это обычно верно - по крайней мере, когда вы используете метод моделирования - потому что повторная вставка db повторно использует тот же документ id, который не будет выполнен во второй попытке. По какой-то причине это не происходит в вашем случае.

И, наконец, проблема, о которой вы описали, ясно показывает, что, вероятно, для дорогостоящей задачи, подобной вашей, должен использоваться другой шаблон. Если бы я был вами, я бы начал, разделив работу на несколько этапов:

  1. Сначала я хотел бы убедиться, что документ загружен на сервер с запросом POST, а не через DDP.
  2. Затем я бы применил метод стороне сервера «process file», который захватывает файл, который уже находится на сервере или в базе данных (в случае, если вы использовали коллекцию файлов). Первое, что должен сделать метод, - это вызвать this.unblock(), но это не все.
  3. Идеально вычислительная задача должна выполняться в отдельном процессе. Только когда этот процесс будет завершен, метод вернет сообщение фактическому вызывающему, что задание выполнено. Но так как мы вызвали this.unblock(), вызывающий может выполнять различные задачи, например. вызывая другие методы/подписки во время ожидания результата.

Иногда раздельный процесс не будет достаточно хорошим.Я столкнулся с ситуациями, когда мне пришлось делегировать задачу другому рабочему серверу.

+0

Работает на стороне клиента. Кроме того, причина, по которой требуется вставить 20 + секунды, была связана с тем, что я проверил данные с пакетом SimpleSchema. Я прекратил это делать, и время ввода было почти мгновенным. – webmagnets

Смежные вопросы