2008-12-16 10 views
1

J'utilise Grails pour envoyer un grand nombre d'emails HTML. J'utilise le SimpleTemplateEngine pour créer mes corps e-mail de cette façon:Groovy/Grails SimpleTemplateEngine Freeze

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 

Voici le modèle que j'essaie de rendre pour chaque corps de l'email:

<!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> 

Une fois que ces méthodes retourne la carte ccIdToEmail, J'envoie tous mes emails. Pour une raison quelconque, la préparation de cette carte de clientContactIds et des corps de messagerie entraîne le blocage de l'application sur l'une des deux lignes répertoriées ci-dessus. Je peux préparer/envoyer avec succès ~ 140 emails avant qu'il ne gèle. Cela arrive très régulièrement.

Est-ce que quelqu'un sait pourquoi cela fonctionnerait mais cesserait de fonctionner après qu'un ~ 140 corps de courriels ont été créés à partir d'un modèle? Je n'ai pas été en mesure de trouver quelque chose en ligne sur d'autres personnes ayant des problèmes avec cela.

Andrew

Répondre

0

Il semble qu'il y avait un problème avec le chargement paresseux mes propriétaires de contact client dans le modèle. Au lieu de s'attendre à ce que les propriétaires soient chargés (inefficacement), alors que SimpleTemplateEngine fait le corps de l'email, je récupère les propriétaires avec empressement avant de lier/créer le corps.

Mon code ci-dessus ressemble maintenant à ceci:

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 

Il est encore un peu inefficace à faire que de nombreuses requêtes pour chacun des clients-contacts, mais il fonctionne. Je ne peux pas expliquer pourquoi le fait de les charger paresseux lors de la fabrication des gabarits a fait geler les grails/groovy, mais c'est le cas. Si quelqu'un peut expliquer cela, je l'apprécierais.

Merci pour vos réponses. Siegfried ... vous m'avez commencé dans la bonne direction.

Andrew

1

Cela ressemble à un problème de synchronisation. Dans un premier temps, vous devez créer le modèle en dehors de la boucle. Comme il n'est pas nécessaire de recréer le modèle à chaque fois.

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 

Si cela ne fonctionne pas, cela pourrait aider si vous postez le contenu du modèle et/ou la source de ClientContact.

HTH, Sigi

+0

J'ai changé mon code pour ce que vous avez, mais il provoque encore le gel à 141. J'essayé simplement créer tous les corps de courrier électronique, mais pas l'envoi et il fonctionne avec 160+. Il y a quelque chose à propos de l'envoi de ces emails qui cause des problèmes. Cependant, à partir de mes instructions println, il semble geler avant d'envoyer. – anschoewe