Groovy / Grails SimpleTemplateEngine зависает - PullRequest
1 голос
/ 16 декабря 2008

Я использую 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 тел сообщений? Я не смог найти в Интернете ничего о том, что у других людей возникли проблемы с этим.

Andrew

Ответы [ 2 ]

1 голос
/ 16 декабря 2008

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

    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.

ч, Сиги

0 голосов
/ 17 декабря 2008

Похоже, что возникла проблема с отложенной загрузкой владельцев контактов моего клиента в шаблоне. Вместо того, чтобы ожидать загрузки владельцев (неэффективно), в то время как 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, но это произошло. Если кто-нибудь может это объяснить, я был бы признателен.

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

Andrew

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...