Newsletter - Versenden in Blöcken

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Newsletter - Versenden in Blöcken

Beitrag von kypta » Fr 25. Nov 2005, 18:39

Ich vermute einen Bug im Contenido 4.6.2 Newsletter.

Beschrieb:

Das senden in Blöcken funktioniert leider nicht (Obwohl $oPage->addScript("Refresh", '<meta http-equiv="refresh" content="'.$iDispatchDelay.'; URL='.$sPathNext.'">'); in include.newsletter_send.php nicht mehr als Kommentar drin ist -> siehe http://contenido.org/forum/viewtopic.php?p=58913#58913).

Der erste Block wurde versendet (Da wird die Liste mit den 50 E-Mail-Empfängern angezeigt). Beim zweiten und allen weiteren Blöcken wird zwar die Seite refresht, aber es werden keine E-Mail-Adressen mehr aufgelistet. Auch das errorlog.txt zeigt nur die ersten 50 an.

Gruss Thomas

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Fr 25. Nov 2005, 19:56

Ja, das ist tatsächlich ein Bug.

Begründung:
In der Datei class.newsletter.php gibt es zwei kleine Ungereimtheiten.

1. Die Variabel $counter wird auf Zeile 259 auf Null gesetzt. Das ergibt dann das Problem, dass bei einem neuen Abarbeiten (durch den Refresh) die Bedingung if ($chunksize == 0 || $counter >= $lowborder) (Zeile 278) nicht erfüllt ist und somit auch nichts mehr versendet wird.

Ich habe das korrigiert, indem ich nach Zeile 266

Code: Alles auswählen

$counter = $lowborder;
eingefügt habe.

2. Hat man dass gemacht, kommt man zum zweiten Fehler.
Der While while (($recipient = $recipients->next()) && $counter < $highborder) startet einfach von neuem -> jetzt wird zwar die richtige Anzahl Refresh ausgefüht, aber immer mit den ersten Mail-Adressen.

Ich habe also unmittelbar vor diesem While

Code: Alles auswählen

if (!($counter == 0)){
	for ($tht = 1; $tht <= $counter; $tht++){
		$recipient = $recipients->next();
	}
}
eingefügt. Das "toggelt" die $recipients hoch bis zum "richtigen" nächsten Empfänger.

O.k. das ist kein schöner Code. Nehme jede Verbesserung dankend entgegen.

Gruss
Thomas

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Sa 26. Nov 2005, 00:18

Tja, das ganze hat nur einen Schönheitsfehler - $recipients mit ->next() hochtoggeln führt dann (bei dem getesteten Server bei 650 E-Mail-Adressen) zum timeout. Womit das ganze senden in Blöcken wieder überflüssig wird. Alles auf einmal senden würde wohl in etwa das gleiche Resultat liefern. :cry:

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Sa 26. Nov 2005, 10:35

Muss ich mir ansehen, bisher funktioniert das Senden in Blöcken in meinem System.

Bin heute Nachmittag dran.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Sa 26. Nov 2005, 13:16

array_chunk()?

Da die Variablen für Mailanzahl und Refresh-Anzahl $chunksize und $chunk heissen habe ich mir überlegt, dass da evtl. ja mit array_chunk() gearbeitet werden sollte. Dieser Befehl befindet sich aber nicht (mehr?) in class.newsletter.php.

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Sa 26. Nov 2005, 15:03

Och, das Chunk habe ich mir ausgedacht. Ich sehe mir das mal an, vielleicht kann man da was mit array_chunk optimieren.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Sa 26. Nov 2005, 19:22

Dachte ich es mir doch. Bei V4.6.0 wurde ein Fehler beim Einbinden des Codes gemacht, dieser wurde in V4.6.1 nicht ganz gefixt und in V4.6.2 zwar syntaktisch korrigiert, aber die Funktion ist hinüber.

Den Fix gibt es: [hier]

@Thomas: Bitte verwende den Fix, Deine Änderungen sind nicht notwendig. Die Ungereimtheiten sind keine, der Fehler war woanders (und $counter muss auf 0 gesetzt werden...). Aber ich bin gespannt, ob es dann mit 650 Empfängern klappt.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » So 27. Nov 2005, 00:46

Also, ich habe den Fix installiert. Funktioniert bis 1000 E-Mail-Adressen, dann timed das ganze aus. Der Server hat max_execution_time 30. Im System sind aktuell 2624 E-Mail-Adressen...

Evtl. fragst Du Dich, wie ich verhindere, dass ich die ersten Empfänger jedesmal erneut mit einem Newsletter beglücke. Ich habe im include.newsletter_send.php auf Zeile 49

Code: Alles auswählen

if ($_REQUEST["chunk"]==0) {
		$_REQUEST["chunk"] = 13;
	}
eingefügt. ACHTUNG AN ALLE - DIES IST NUR FÜR DIESE (MEINE) SPEZIELLE SITUATION GEDACHT UND ALS ERKLÄRUNG FÜR HERRB - NICHT NACHMACHEN!
Sind und Zweck war es ja, dass er mit E-Mail auf Zeiger 651 anfängt (Bei Blöcken zu 50 E-Mails) und nicht etwa bei 1 (Die ersten 650 haben ja jetzt den Newsletter). Also heisst das, das ich jetzt mit dem fix noch weitere 350 E-Mails versenden konnte.

Ich denke, das Problem liegt beim Auslesen der E-Mail-Adressen aus der DB. Wenn er mehr als die Tausend auslesen muss überschreitet er ganz einfach die max_execution_time. Wenn das tatsächlich so ist müsste wohl das SQL-Statement geändert werden. Siehst Du das auch so?

Gruss
Thomas

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » So 27. Nov 2005, 12:17

Ja. Das Problem hierbei ist die gewünschte Plattformunabhängigkeit. In mySQL kann ich da locker ein SQL-Statement zaubern (LIMIT), bei Oracle gibt es sowas m.W. nicht (wenn ich mich recht erinnerem, kann man zwar die Menge begrenzen, aber nicht sagen, dass erst ab Datensatz 5711 angefangen werden soll). Beim SQL-Server weiss ich es gerade nicht.

Ich gucke es mir nochmal an, wird aber ein paar Tage dauern. Wenn ich nix übergreifendes finde, fixe ich das erstmal mit einem LIMIT.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » So 27. Nov 2005, 14:45

Kaum zu glauben. Da der Newsletter raus musste habe ich in der db-tabelle con_news_rcp die ersten Tausend entfernt, include.newsletter_send.php ohne meine obige Änderung (der if chunck == 0, chunk = neuer wert) nochmals hochgeladen und den Newsletter nochmals an "alle" versendet.

Jetzt hat es der Server tatsächlich geschafft, alle restlichen Empfänger zu bemailen. Immerhin 1624 Stück!

Da frage ich mich natürlich, ob der Server gestern in der Nacht unter höherer Last stand (z.B. Backup)? Wie dem auch sei, es ändert wohl am Grundproblem nichts.

Ich denke, ich werde vorerst die Empfänger schön in Grüppchen von ca. 500 Empfänger aufteilen und dann jeweils nur eine Gruppe auf einmal bemailen.
Die Ungereimtheiten sind keine, der Fehler war woanders
Darf ich Dich fragen, wo "woanders" ist, damit ich den Code besser verstehen kann (offensichtlich lag ich da ja weit daneben)?

Gruss
Thomas

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Mo 28. Nov 2005, 00:25

Darf ich Dich fragen, wo "woanders" ist, damit ich den Code besser verstehen kann (offensichtlich lag ich da ja weit daneben)?
Jetzt habe ich es extra blumig formuliert... aber gerne: Die Plattformunabhängigkeit erfordert zunächst, dass alle Datensätze abgerufen und anschließend nur die versendet werden, die dran sind (wie gesagt, kein LIMIT wenn keine mySQL-DB).

Daher muss der $counter bei 0 beginnen, da er sich zunächst mit next_record zur unteren Grenze hocharbeitet - dann sendet er und an der oberen Grenze hört er mit dem Senden auf (bricht auch die Schleife ab).

In V4.6.2 sind die Klammern ein bisschen durcheinander gekommen - und das hatte zur Folge, dass der $counter nicht generell, sondern nur dann hochgezählt wird, wenn es was zu Senden gibt (und das ist nur beim ersten Mal der Fall). Außerdem gab es keinen Rückgabewert, wenn Probleme aufgetreten wären. Die geklammerten Zeilen sind praktisch eine Ebene verschoben worden, bildlich gesprochen.

Noch ein Tipp, bis es was neues gibt: In Gruppen ist natürlich auch eine Lösung, aber löschen musst Du die Empfänger nicht - es genügt, wenn Du sie in der DB deaktivierst...

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Mi 14. Dez 2005, 19:25

Och, das Chunk habe ich mir ausgedacht. Ich sehe mir das mal an, vielleicht kann man da was mit array_chunk optimieren.
Ist das immer noch eine Möglichkeit? LIMIT bringt ja die mySQL-Bindung.

Die Lösung, wie sie momentan steht, klappt ja nur sehr unzuverlässig. Der Kunde hat wieder einen NL versendet - natürlich gleich "an alle". Welche Überraschung, nach 250 Empfängern kam der Timeout.

Hat sich in dieser Beziehung (Newsletter) noch was geändert zwischen der 4.6.2 mit Bugfix und der 4.6.4 oder wäre ich soweit aktuell?

Gruss Thomas

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Mi 14. Dez 2005, 22:06

Nein, Du bist aktuell.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Mi 14. Dez 2005, 22:40

Mal dumm gefragt: Du baust ja auf der RecipientCollection aus class.newsletter.recipients.php auf. Diese baut auf der ItemCollection aus class.genericdb.php auf. Und wenn ich in der api die Doku-Seite classItemCollection.html anschaue, dann hat diese ItemCollection ja beim Select die Parameter ($where="", $group_by="", $order_by="", $limit=""). Wobei mich natürlich $limit ganz besonders interessiert. Die Frage lautet also: Wenn Timo $limit zur Verfügung stellt, dann müsste doch Timo die Kompatibilität mit anderen SQL-DBs geprüft haben und den Code in class.genericdb.php entsprechend gestrickt haben? Warum sollen wir also nicht eben dieses $limit verwenden? Oder habe ich da einen Denkfehler?

Gruss
Thomas

kypta
Beiträge: 295
Registriert: Di 8. Jul 2003, 13:25
Kontaktdaten:

Beitrag von kypta » Mi 14. Dez 2005, 22:59

Dann könnte evtl. dieser Code ja funktionieren:

Code: Alles auswählen

			case "all" :
				$recipients = new RecipientCollection;
				// das Limit-Statement vorbereiten
				if ($chunksize != 0) // wenn kein chunksize da ist macht limit auch keinen sinn, oder?
				{
					if ($chunk != 0)
					{
						$initial_record = $chunk * $chunksize;
						$limit_statement = $initial_record.",".$chunksize;
					}
					else
					{
						$limit_statement = "";
					}
				}

				// select($where="", $group_by="", $order_by="", $limit="")
				$recipients->select("deactivated='0' AND confirmed='1' AND idclient='$client' AND idlang='$lang'","","","$limit_statement");
				break;
-> das ist in der class.newsletter.php beim switch ($destination) der "case all".
Habe ich natürlich nicht getestet :wink: Ist nur eine Überlegung. Würde wohl auch noch include.newsletter_send.php anpassen müssen...

Gesperrt