Archive of UserLand's first discussion group, started October 5, 1998.

Offloading email sending

Author:Dave Winer
Posted:7/9/1999; 10:28:03 PM
Topic:Offloading email sending
Msg #:8379
Prev/Next:8378 / 8380

We've been doing more and more offloading of non-HTTP-server functions from our main server to what was once a spare machine and now is a workhorse on our LAN.

There are two tasks that it's doing for us. First, it reads all the My.UserLand.Com channel files once per hour. It writes them to a folder that the main server checks once a minute.

The second task for the offload server is watching a folder for XML formatted email messages. The XML says who the sender is, who it's going to, a subject, a cc and bcc list, a mimetype, and a body. Here's a simple example:
	Testing XML-Mail,
	Hello World!

Over on the web server, I stubbed off tcp.sendMail so that instead of sending a mail message, it writes out one of these files in the same folder that the offload server is watching. Here's the routine that my copy of tcp.sendMail is calling:

on offloadedMailSender (recipient="", subject="", body="", sender=user.prefs.mailAddress, cc="", bcc="", mimeType="text/plain") {
	local (folder = "h:\\macshare\\xmlMail\\");
	local (xmltext);
	on add (s) {
		xmltext = xmltext + s + "\r"};
	on clean (s) {
		s = string.replaceall (s, "&", "&");
		s = string.replaceall (s, "<", "<");
		s = string.replaceall (s, ">", ">");
		return (s)};
	add ("");
	add ("");
	add ("" + clean (recipient) + "");
	add ("" + clean (subject) + "");
	add ("" + clean (sender) + "");
	if cc != "" {
		add ("" + clean (cc) + "")};
	if bcc != "" {
		add ("" + clean (bcc) + "")};
	add ("" + clean (mimeType) + "");
	add ("" + clean (body) + "");
	add ("");
	loop { //get a unique name
		local (f = folder + clock.ticks () + ".xml");
		file.surefilepath (f);
		if not file.exists (f) {
			file.writewholefile (f, xmltext);

Over on the offload server, here's what it's doing every five seconds:

local (f);
fileloop (f in config.batchJobServer.prefs.mailFolder, infinity) {
	local (adrlog = log.addToGuestDatabase ("xmlMail"));
	try { //an error in a file doesn't kill the script
		local (xmltext = string (file.readwholefile (f)), xtable);
		file.delete (f);
		local (recipient, subject, body, sender=user.prefs.mailAddress, cc="", bcc="", mimeType="text/plain");
		xml.compile (xmltext, @xtable);
		local (adrmail = xml.getaddress (@xtable, "mail"));
		on getmailvalue (valname) {
			local (s = xml.getvalue (adrmail, valname));
			s = string.replaceall (s, "&lt;", "<");
			s = string.replaceall (s, "&gt;", ">");
			s = string.replaceall (s, "&amp;", "&");
			adrlog^.[valname] = s;
			return (s)};
		bundle { //get the required values
			recipient = getmailvalue ("recipient");
			subject = getmailvalue ("subject");
			body = getmailvalue ("body")};
		bundle { //get the optional values
			try {cc = getmailvalue ("cc")};
			try {bcc = getmailvalue ("bcc")};
			try {mimeType = getmailvalue ("mimeType")};
			try {sender = getmailvalue ("sender")}};
		tcp.sendMail (recipient, subject, body, sender, cc, bcc, mimeType:mimeType, flMessages:true)}
	else {
		adrlog^.error = tryerror}}

Now when a MailToTheFuture message goes out, or a password confirmation, or a Bulletin, it will flow thru the offload server. So every time you get an automatic email from UserLand, think to yourself "This code is still working."

This page was archived on 6/13/2001; 4:51:21 PM.

© Copyright 1998-2001 UserLand Software, Inc.