Monday, November 08, 2010 at 12:02 AM.
system.verbs.apps.xmlStorageSystem.writeFile
on writeFile (email, password, relativepath, filetext, adrurl = nil, adrmsg = nil, adrdata = @xmlStorageSystem.data, flShowMessages = true) {
<<Changes
<<4/2/01; 8:06:56 AM by DW
<<Created. This is the core routine in xmlStorageSystem.
<<email/password identify an account in the cloud.
<<relativepath is a string, like myLists/todo/april2.xml, it says where the file is to be stored in the cloud, relative to the user's root directory.
<<filetext is a string, containing the text of the file.
<<6/25/01; 1:32:18 PM by JES
<<Don't attempt to set adrurl^ if the server's response does not include a urllist.
<<Commented out test code.
<<7/23/01; 9:45:30 PM by JES
<<The data table now supports both xmlRpcPath, and the more general rpcPath, used for both XML-RPC and for SOAP. This is for support for SOAP-based xmlStorageSystem implementations which have a request URI which is different from the value of the SOAPAction header.
<<8/14/01; 3:14:00 AM by JES
<<New optional parameter: flShowMessages. This flag is passed to xml.rpc, which in turn is passed to tcp.httpClient. Default is true, which preserves existing behavior.
local (params = {"email":email, "password":string.hashmd5 (password), "relativePathList":{relativepath}, "fileTextList":{string (filetext)}});
local (rpcPath);
if defined (adrdata^.xmlRpcPath) {
rpcPath = adrdata^.xmlRpcPath};
if defined (adrdata^.rpcPath) {
rpcPath = adrdata^.rpcPath};
with adrdata^ {
local (response = xml.rpc (server, port, "xmlStorageSystem.saveMultipleFiles", @params, rpcPath:rpcPath, fldebug:fldebug, flShowMessages:flShowMessages, protocol:protocol, soapAction:soapAction));
if adrurl != nil {
if defined (response.urllist) {
adrurl^ = response.urllist [1]}};
if adrmsg != nil {
adrmsg^ = response.message};
return (not response.flerror)}};
<<bundle //test code
<<local (url)
<<with user.xmlStorageSystem
<<writeFile (email, password, "/test/clock2.html", clock.now (), @url)
<<webbrowser.openurl (url)
<<bundle //synchronous benchmark code
<<local (ct = 0, totalticks = 0, n = 300)
<<for i = 1 to n
<<local (now = clock.ticks ())
<<with user.xmlStorageSystem
<<writeFile (email, password, "/test/clock2.html", clock.now (), @url, flShowMessages: false)
<<local (ticks = clock.ticks () - now)
<<ct++
<<totalTicks = totalTicks + ticks
<<msg (ct + "; " + totalTicks + "; " + double (totalTicks) / ct)
<<dialog.alert ("For " + n + " requests, total ticks: " + totalTicks + "; avg: " + double (totalTicks) / ct + ".")
bundle { //asynchronous benchmark code
<<bundle //copy the script below to a script object at workspace.doRequest
<<on doRequest (adrCt, adrTotalTicks, adrCtThreads)
<<try
<<adrCtThreads^++
<<local (now = clock.ticks ())
<<with user.xmlStorageSystem
<<xmlStorageSystem.writeFile (email, password, "/test/clock" + adrct^ + ".html", clock.now (), @url, flShowMessages: false)
<<local (ticks = clock.ticks () - now)
<<adrCt^++
<<adrTotalTicks^ = adrTotalTicks^ + ticks
<<adrCtThreads^--
local (ct = 0, totalticks = 0, n = 600, maxThreads = 20, ctThreads = 0);
local (now = clock.ticks ());
for i = 1 to n {
if ct > 0 {
workspace.avg = double (clock.ticks () - now) / ct;
msg (i + "; " + totalTicks + "; " + workspace.avg)};
while ctThreads >= maxThreads {
thread.sleepTicks (1)};
thread.callScript (@workspace.doRequest, {@ct, @totalTicks, @ctThreads})};
while ctThreads > 0 {
thread.sleepTicks (1)};
local (later = clock.ticks ());
local (time = later - now);
dialog.alert ("For " + n + " requests, total ticks: " + time + "; avg: " + double (time) / ct + ".")}
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.