Groovy / Grails SimpleTemplateEngine зависает

Я использую Grails для отправки большого количества электронных писем в формате HTML. Я использую SimpleTemplateEngine для создания тел сообщений электронной почты следующим образом:

def ccIdToEmailMap = [:]
def emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
def engine = new SimpleTemplateEngine()
def clientContacts = ClientContact.list()
for(ClientContact cc in clientContactList) {
   def binding = [clientContact : cc]

   //STOPS (FREEZES) EITHER HERE OR....
   def template = template = engine.createTemplate(emailTemplateFile).make(binding)

   //OR STOPS (FREEZES) HERE
   def body = template.toString()

   def email = [text: body, to: cc.emailAddress]
   ccIdToEmailMap.put(cc.id, email)
   println "added to map"
}
return ccIdToEmailMap

Вот шаблон, который я пытаюсь визуализировать для каждого тела письма:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">


<html>
<head>
<title>Happy Holidays from google Partners</title>
</head>

<body>
    <table width = "492" cellpadding = "0" cellspacing = "0" style = "border:2px solid #acacac;margin:8px auto;" align = "center">
        <tr>
            <td colspan = "5" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/cardbg.gif" width = "492" height = "10" border = "0"></td>
        </tr>

        <tr>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgl.gif" width = "6" height = "453" border = "0"></td>
            <td style = "background:#fff;border:1px solid #acacac;padding:2px;" width = "228">
                <div style = "width:208px;margin:4px 8px 0px 8px; color:#515151;">
                <font face = "Times New Roman" size = "2">
                <span style = "font:14px 'Times New Roman',times,serif;">Static text that is the same for each email
                <br>&nbsp;<br>
                More text
                <br>&nbsp;<br>
                We wish you health and happiness during the holidays and a year of growth in 2009.
                </span>
                </font>
                </div>
            </td>
            <td style = "background:#c9f4fe;border-top:1px solid #acacac;border-bottom:1px solid #acacac;" width = "5"><img src = "http://www.google.com/holiday2008/vertbg.gif" border = "0" height = "453" width = "5"></td>
            <td width = "247" style = "background:#fff;border:1px solid #acacac;"><img src = "http://www.google.com/holiday2008/snowing.gif" width = "247" height = "453" border = "0"></td>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgr.gif" width = "6" height = "453" border = "0"></td>
        </tr>
        <tr>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgr.gif" width = "6" height = "38" border = "0"></td>
            <td colspan = "3" style = "border:1px solid #acacac;" align = "center"><img src = "http://www.google.com/holiday2008/happyholidays.gif" width = "480" height = "38" alt = "Happy Holidays" border = "0"></td>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgr.gif" width = "6" height = "38" border = "0"></td>
        </tr>
        <tr>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgr.gif" width = "6" height = "120" border = "0"></td>
            <td colspan = "3" style = "background-color#fff;border:1px solid #acacac;padding:2px;" valign = "top">
                <img src = "http://www.google.com/holiday2008/gogl_logo_card.gif" width = "140" height = "40" alt = "google partners" border = "0" align = "right" hspace = "4" vspace = "4" />
                <font face = "Times New Roman" size = "2">
                <div style = "padding:4px;font:12pt 'Times New Roman',serif;color:#515151;">
                <span style = "font-size:10pt"><i>from:</i></span>

                    <div style = "padding:2px 4px;">
                        <% clientContact.owners.eachWithIndex { it, i -> %>
                            <% if (i < (clientContact.owners.size() - 1)) { %>
                                ${it.toString()},
                            <% }else { %>
                                ${it.toString()}
                            <% } %>
                        <% } %>
                    </div>
                </div>
                </font>
            </td>
            <td width = "6" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/sidebgr.gif" width = "6" height = "120" border = "0"></td>
        </tr>
        <tr>
            <td colspan = "5" bgcolor = "#c1e0f3"><img src = "http://www.google.com/holiday2008/cardbg.gif" width = "492" height = "10" border = "0"></td>

        </tr>
    </table>
</body>
</html>

Как только эти методы вернут карту ccIdToEmail, я отправлю все свои электронные письма. По какой-то причине подготовка этой карты clientContactIds и тел электронной почты приводит к зависанию моего приложения на любой из двух строк, перечисленных выше. Я могу успешно подготовить / отправить ~ 140 писем, прежде чем он зависнет. Это происходит очень стабильно.

Кто-нибудь знает, почему это сработает, но перестанет работать после создания ~ 140 тел электронной почты из шаблона? Я не смог найти в Интернете ничего о других людях, у которых возникли проблемы с этим.

Андрей

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 899
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже на проблему с синхронизацией. В качестве первого шага вы должны создать шаблон вне цикла. Так как нет необходимости каждый раз заново создавать шаблон.

    def ccIdToEmailMap = [:]
    def emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
    def engine = new SimpleTemplateEngine()
    def template = engine.createTemplate(emailTemplateFile)
    def clientContacts = ClientContact.list()
    for(ClientContact cc in clientContactList)
    {
            def binding = [clientContact : cc]
            def body = template.make(binding).toString()
            def email = [text: body, to: cc.emailAddress]
            ccIdToEmailMap.put(cc.id, email)
            println "added to map"
    }
    return ccIdToEmailMap

Если это не поможет, может помочь, если вы разместите содержимое шаблона и / или источник ClientContact.

hth, Сиги

Я изменил свой код на тот, что есть у вас, но он по-прежнему вызывает зависание на 141. Я попытался просто создать все тела электронной почты, но не отправлять, и он работает с 160+. В отправке этих писем есть что-то, что вызывает проблемы. Однако, судя по моим выводам println, перед отправкой он зависает.

anschoewe 16.12.2008 21:07
Ответ принят как подходящий

Похоже, что возникла проблема с отложенной загрузкой моих владельцев контактов с клиентами в шаблон. Вместо того, чтобы ожидать загрузки владельцев (неэффективно), в то время как SimpleTemplateEngine создает тело письма, я с нетерпением вызываю владельцев перед привязкой / созданием тела.

Мой приведенный выше код теперь выглядит так:

    def emailTemplateFile = null
    def ccIdToEmailMap = [:]

    emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
    def engine = new SimpleTemplateEngine()
    def template = engine.createTemplate(emailTemplateFile)
    for(ClientContact cc in clientContactList)
    {
        //there was a locking problem when we tried to create the template for too many client contacts
        //i believe it was caused by lazy-fetching of the person/owners.  So, I fetch them before we bind
        //and make the email body.
        def criteria = ClientContact.createCriteria()
        cc = criteria.get {
            eq("id", cc.id)
            fetchMode('relationship', FM.EAGER)
            fetchMode('relationship.person', FM.EAGER)
        }
        def binding = [clientContact : cc]
        def body = template.make(binding).toString()
        def email = [text: body, to: cc.emailAddress]
        ccIdToEmailMap.put(cc.id, email)
    }

    return ccIdToEmailMap

По-прежнему неэффективно делать такое количество запросов для каждого из контактов клиента, но ЭТО РАБОТАЕТ. Я не могу объяснить, почему ленивая загрузка их во время создания шаблона привела к зависанию grails / groovy, но это было так. Если кто-нибудь может это объяснить, я был бы признателен.

Спасибо за ваши ответы. Зигфрид ... ты направил меня в правильном направлении.

Андрей

Другие вопросы по теме