From baloghrobi@REDACTED Sun Feb 1 01:39:12 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Sun, 01 Feb 2004 01:39:12 +0100 Subject: dbg question Message-ID: Hi Vance, Thanks for your advice. I check the pid, and it is true. Look: Erlang (BEAM) emulator version 5.3 [threads:0] Eshell V5.3 (abort with ^G) (axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). <0.37.0> (axd301@REDACTED)2> is_pid(Pid). true (axd301@REDACTED)3> dbg:stop_trace_client(Pid). =ERROR REPORT==== 1-Feb-2004::01:36:23 === Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: {badarg,[{erla ng,exit,[{badpid,<0.37.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app ly,5},{shell,eval_loop,2}]} ** exited: {badarg,[{erlang,exit,[{badpid,<0.37.0>},abnormal]}, {dbg,stop_trace_client,1}, {erl_eval,do_apply,5}, {shell,eval_loop,2}]} ** (axd301@REDACTED)4> But I can not to stop this process :-(. Thanks four your help, regards, /Robi >From: Vance Shipley >To: Robert Balogh >Subject: Re: dbg question >Date: Sat, 31 Jan 2004 17:01:17 -0500 > >Robi, > >Make sure the process is still there: > >(axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). ><0.37.0> >(axd301@REDACTED)2> is_pid(Pid). >true > >If it doesn't say "true" then it is gone. If it does say true >I don't know. > > -Vance > _________________________________________________________________ The new MSN 8: advanced junk mail protection and 2 months FREE* http://join.msn.com/?page=features/junkmail From ulf.wiger@REDACTED Sun Feb 1 11:06:35 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sun, 01 Feb 2004 11:06:35 +0100 Subject: dbg question In-Reply-To: References: Message-ID: Actually, is_pid/1 will only tell you that the type of Pid is pid(). Use is_process_alive(Pid) to find out if it is still there. Eshell V5.3 (abort with ^G) 1> Pid = spawn(fun() -> exit(normal) end). <0.31.0> 2> is_pid(Pid). true 3> is_process_alive(Pid). false 4> Pid2 = spawn(fun() -> timer:sleep(30000) end). <0.35.0> 5> is_process_alive(Pid2). true 6> On Sun, 01 Feb 2004 01:39:12 +0100, Robert Balogh wrote: > Hi Vance, > > Thanks for your advice. I check the pid, and it is true. Look: > > Erlang (BEAM) emulator version 5.3 [threads:0] > > Eshell V5.3 (abort with ^G) > (axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > <0.37.0> > (axd301@REDACTED)2> is_pid(Pid). > true > (axd301@REDACTED)3> dbg:stop_trace_client(Pid). > > =ERROR REPORT==== 1-Feb-2004::01:36:23 === > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > {badarg,[{erla > ng,exit,[{badpid,<0.37.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > ly,5},{shell,eval_loop,2}]} > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.37.0>},abnormal]}, > {dbg,stop_trace_client,1}, > {erl_eval,do_apply,5}, > {shell,eval_loop,2}]} ** > (axd301@REDACTED)4> > > > But I can not to stop this process :-(. > > Thanks four your help, > > regards, > /Robi > > >> From: Vance Shipley >> To: Robert Balogh >> Subject: Re: dbg question >> Date: Sat, 31 Jan 2004 17:01:17 -0500 >> >> Robi, >> >> Make sure the process is still there: >> >> (axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). >> <0.37.0> >> (axd301@REDACTED)2> is_pid(Pid). >> true >> >> If it doesn't say "true" then it is gone. If it does say true >> I don't know. >> >> -Vance >> > > _________________________________________________________________ > The new MSN 8: advanced junk mail protection and 2 months FREE* > http://join.msn.com/?page=features/junkmail > -- Ulf Wiger From baloghrobi@REDACTED Sun Feb 1 11:54:03 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Sun, 01 Feb 2004 11:54:03 +0100 Subject: dbg question Message-ID: Hi Ulf, I checked this Pid, and unfrotunatelli is not alive. Erlang (BEAM) emulator version 5.3 [threads:0] Eshell V5.3 (abort with ^G) (axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). <0.37.0> (axd301@REDACTED)2> is_pid(Pid). true (axd301@REDACTED)3> is_process_alive(Pid). false How possible to start this dbg client? Do you have any idea? I read the dbg module quide about 10 times, and at this time I think I don't understand how works it :-( tahnks, Robi >From: Ulf Wiger >To: erlang-questions@REDACTED >Subject: Re: dbg question >Date: Sun, 01 Feb 2004 11:06:35 +0100 > > >Actually, is_pid/1 will only tell you that the type of >Pid is pid(). Use is_process_alive(Pid) to find out if >it is still there. > >Eshell V5.3 (abort with ^G) >1> Pid = spawn(fun() -> exit(normal) end). ><0.31.0> >2> is_pid(Pid). >true >3> is_process_alive(Pid). >false >4> Pid2 = spawn(fun() -> timer:sleep(30000) end). ><0.35.0> >5> is_process_alive(Pid2). >true >6> > >On Sun, 01 Feb 2004 01:39:12 +0100, Robert Balogh >wrote: > >>Hi Vance, >> >>Thanks for your advice. I check the pid, and it is true. Look: >> >>Erlang (BEAM) emulator version 5.3 [threads:0] >> >>Eshell V5.3 (abort with ^G) >>(axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). >><0.37.0> >>(axd301@REDACTED)2> is_pid(Pid). >>true >>(axd301@REDACTED)3> dbg:stop_trace_client(Pid). >> >>=ERROR REPORT==== 1-Feb-2004::01:36:23 === >>Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: >>{badarg,[{erla >>ng,exit,[{badpid,<0.37.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app >>ly,5},{shell,eval_loop,2}]} >> >>** exited: {badarg,[{erlang,exit,[{badpid,<0.37.0>},abnormal]}, >> {dbg,stop_trace_client,1}, >> {erl_eval,do_apply,5}, >> {shell,eval_loop,2}]} ** >>(axd301@REDACTED)4> >> >> >>But I can not to stop this process :-(. >> >>Thanks four your help, >> >>regards, >>/Robi >> >> >>>From: Vance Shipley >>>To: Robert Balogh >>>Subject: Re: dbg question >>>Date: Sat, 31 Jan 2004 17:01:17 -0500 >>> >>>Robi, >>> >>>Make sure the process is still there: >>> >>>(axd301@REDACTED)1> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). >>><0.37.0> >>>(axd301@REDACTED)2> is_pid(Pid). >>>true >>> >>>If it doesn't say "true" then it is gone. If it does say true >>>I don't know. >>> >>> -Vance >>> >> >>_________________________________________________________________ >>The new MSN 8: advanced junk mail protection and 2 months FREE* >>http://join.msn.com/?page=features/junkmail >> > > > >-- >Ulf Wiger > _________________________________________________________________ STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail From p0rj2el602@REDACTED Sun Feb 1 14:36:53 2004 From: p0rj2el602@REDACTED (Lon Willett) Date: 1 Feb 2004 13:36:53 -0000 Subject: failure notice Message-ID: <5172-41674@sneakemail.com> Hi. This is the qmail-send program at monkey.sneakemail.com. I'm afraid I wasn't able to deliver your message to the following addresses. This is a permanent error; I've given up. Sorry it didn't work out. : 66.111.4.31 failed after I sent the message. Remote host said: 550 Error: Possible Novarg virus blocked 2 --- Below this line is a copy of the message. Return-Path: Received: (qmail 11076 invoked by uid 501); 1 Feb 2004 13:36:52 -0000 Message-ID: <20040201133652.11075.qmail@REDACTED> Received: from 81-196-92-131.arad.cablelink.ro (HELO erlang.org) (81.196.92.131) by mail.sneakemail.com with SMTP; 1 Feb 2004 13:36:52 -0000 From: "erlang-questions-at-erlang.org |erlang|" To: p0rj2el602@REDACTED Subject: HI Date: Sun, 1 Feb 2004 15:36:46 +0200 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0005_60A29288.7CBF4122" X-Priority: 3 X-MSMail-Priority: Normal This is a multi-part message in MIME format. ------=_NextPart_000_0005_60A29288.7CBF4122 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: 7bit Mail transaction failed. Partial message is available. ------=_NextPart_000_0005_60A29288.7CBF4122 Content-Type: application/octet-stream; name="document.scr" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="document.scr" TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUEUAAEwBAwAAAAAA AAAAAAAAAADgAA8BCwEHAABQAAAAEAAAAGAAAGC+AAAAcAAAAMAAAAAASgAA EAAAAAIAAAQAAAAAAAAABAAAAAAAAAAA0AAAABAAAAAAAAACAAAAAAAQAAAQ AAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAADowQAAMAEAAADAAADoAQAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAABVUFgwAAAAAABgAAAAEAAAAAAAAAAEAAAAAAAAAAAAAAAA AACAAADgVVBYMQAAAAAAUAAAAHAAAABQAAAABAAAAAAAAAAAAAAAAAAAQAAA 4C5yc3JjAAAAABAAAADAAAAABAAAAFQAAAAAAAAAAAAAAAAAAEAAAMAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMS4y NABVUFghDAkCCUh+iY/UNhyBKZYAAFNOAAAAgAAAJgEAxe6HApIAUCZKAEAD /bJpmiwQBPQl6AEAS85pmm7ZH8gqwAO4sKimaZqmoJiQiICapmmaeHBoYFhQ zWCfaUgARAc4MDRN03QDKCQcGBDTLLvXCCMD+Cnw6E3TNE3g2NDIvLQ0TdM0 rKSclIzONk3TiHxwaClvXKbpmsEHVEwDRDiapmmaLCQcFAwEaZrObfwofwP0 7OSmaZqm3NTMyLyapmmatKykoJiQZ5umaYyAeHAoe2jebNN1B1wDVEwo//sL drb740APNCj3LC8DmqYZ+SQoShwUDARpms7sm/wnA+zo4KZpmqbY1MzIwJqm abq4J7CsqKCYaZqmaZSMiIR8pGmapnRsZFxUaZqmG0wDREA4MKZpmqYoIBgQ CJqmc5sA+CbPA+jg2Gebzm1UNEMDQDQ024r/////nVrQ2uX0Bh8zTmxyTtgC l1+SyAE9fL5DS5bkNYngOpf/////91rAKZUEdutj3lzdYehy/48iuFHtjC7T eybUDTnwqmf/////J+qweUUU5ruTbkwtEfjiz7+yqKGdnJ6jq7bE1ekAGjf/ ////V3qgyfUkVovD/jx9wQhSn+9CmPFNrA5z20a0JZkQigf/////hwqQGaWl qP7yw9Ko+BIsSmuPtuANPXCm3xtafOEnVcn/////EmC+GGXVOJ4Xc+JUiUG8 muM/xlCNbQCWT8tqDLFDerL/////cxfOiEcFyIpXI/LEmXFMLgvv1sCtnZCG D3t6fJGJlKL/////s8fe+hU1WH6nwwI0eaHcGluP5jBtzSB2zyuK/FG5JJL/ ////A3fuaOVl6G6Xg4N2jJWhsMLX7wooSW2UvusbToS9+Tj/////er8HUqDx RWyWU7MafOVRwDKnH5oYmR2kLrtL3nQNqUj/////6o834pBB9axmI+OmbDUB 0KJ3TyoI6c20not7bmRdWVj/////Wl9ncoCRpbzW8xM2XIWx4BJHf7r4OX3E Dlur/lStCT3/////mnenAnDhVcwGw0PGXNVhYWRqc3+MoLXN6AYnS3Kcyfn/ ////LGKbVxZYfbBgJv4jetQxkeRawy/OEIX9dPZ3+4AMmSn/////vFLrhybI bRXAbh+TikThlNQSId+ugFUtGObHq/J8aVn/////TkI7Nzg4PUVQXm+DmrTR 8RQ6Y8++8OVstuQjW/e8Yaj/////0DuJ7nM8Y/iZ4MVLkRehId4isz8/VEhR e29+1s/ZbpX/3/7/KQMj6ZQJv+bzpUEQpnwyaWuAIQstx07SEIJs+f////9z p3feFIcHB/tSqgFhwCyb9yaW3ZedImAPRp7N/SxAf/////+TstLxCSBYdmhj XVBSUVNqZHcBLMXvVDC8VxE8zp1Xbv////8g461g2tFSFc5mX7dBwBTkZZOf eP5yDbznapV7exN2dv////99HA0t8vb0sPHR53n63Uxlo/8nbIzdC9uMG6m9 dYc7T//////bFIJCFAlFzIIP+mK3KXP7FYPnHpN+tCRpKf+9KMvqTv//7f93 Djqwv/dU1OxzmAFNBp3yoq/CYvPlXjffBXFS/////wf4G0B+VD6nqU8sAn0w yOcG0lQqGmtMAZ0E9mr6HccG/4X///gdkASrlgAGBhAr75nUTv8XeAuTxvh1 IYyk/////1//zHJr62/+pf3s0EHJeJHZxKwmx+jgqbcaXW/sKRCj/////7zz 7fVvUSE1jdZTHEgpGOO3XD+duM3QUlXjtUPqvmfj/////6CgMuLOSTokLzAK j66E4XVAoWKYsvUwSuDj/5GBwScH/////3eIZ49Us4UI4v6CRathjnTauyo4 rvBK1BicF4pIwrW8/////577H1bmbpDgO0ezoBq30qq8xPeTSKYBwAT/BhKL XanY/////72UMfgf6FpjPt/WCspC1QxeYEly9fSu9FMX/BYV8o6a/////3Nw PIKx4o43W1MWoieUVFissTU3Pqp1ZZUhbusahIFq/////+YKGD86lZ+BguNz pEc9CQLWLojCp9U/ilzqn1Y7Xz1K/9L//8N5X0MJuPCrms4esoXZS8HUO17P 3/ZH+Ur3/////9j7LbSKZ2L/WK0RjCL3W8tY34X8rOBl2uuXlOJgCO8///// /zzj7H8QjmB+3U2b5J0FG5d628yz+zePJfE5HbJ8GvUd/////x+9n+nG6unr PtmWcP072kUl9vOk59YEIUw5/lukh4mS////C53TsFuNKjZCG8rR5DRQrMMc xeFmimxbM1FC/////+0+I6ti1+6U9DSy6dVJrF4mrrxteWeVWzeGpII9rofD /////4ewgLbfQ9+7i4BlLx6oMsu1KpM3Q3niYjRauu1pXGwi/////6wY1XPh 68iGL1pJT/FD8zfLbzYYPWctofGYQhK4DcHK/7f//2sKa/gFjY0HnpfoiFC2 srjZ8zKBX9p+X/fQHQ3/////ShsDOn0PPwtPGPEr4Yi1NyT31AcfN2/Na5Bd QpaXn6L/////n50vJlZAhvcbrLVavCc7JKSdidPIpU82+mgAvj5dGdb/2/// 9ckUyfDkjiw2iQvghuvRCwoz07M2hpLkvYowoP/////HuV680N6rwchK14K/ XeWgnpOQJdhALzGgCaazMAGh2P////9frZFovBhyOfUsoWNhix4aQSY3G0eq 2fC7xeYx4EwsaTf+///o+hHGcPdD+0ei2qDV9yjFv7WVcNEE9fBNaRv8//// lj2TBqUsujl4DNudAiPDmVWWhFuHQjz/////MzSANfYd8ySmXsbvONrcqoff 2HIvP8Tk9pY2j0Q1R/X/////QdWRJmlnyhPaLDJtCSkRc1pBVgs6PfBSHawv phrwt/r//0v/MRQml5IPtKQsvl7QDM/PtwBr03qRVDiIkrH/N2j/5Qrn4JUl msjO1oIDpc578bTzHTb//1/4sAzRf5GPJf5SijZ1a+/bwdkjxg8+dRWkwP3/ ////vLrDPAha53OGbtWwV3A6D36k3FDVQj8Pjq8/q+BAc+P///8bwlx/iRSy +e0DGCL+C48qlJUdTWH6Jm9hE4O/8P///h3CDD375n8/KDSeK68izSmi62dc uGhJfmZLf4P/wKqq0yrLdWigKKdI39unGj0l/////yQF1+Xs4O3i+PkOZ5dW kbv0XM3X35G6tz+5ml2IrF05/xb//+xxa5fsK8AuCGjFnVkbCQvvGbZTWZVZ D/////8Sdvmb1JGvTrBBSKDuhyimZ58Oxz9PyLYCxZlctWRzDr/E//+bALZB VBTrCYPqxQD5jmVeaGEU9uPhUpP/wv//2shfm3fGoonK0uTbIvEfjxzJrtVA eLhM3Hz/////8cmzboBqoIUrhLngq83ncX+3mzFatZHSCDRwTowmo2m/9P9v NQibXZvIi1v9QJbcQFjMEOr8sIvFbf////+Lst8d93QR3CapECBKfjJBvuVh S+lyfye8BkOTUvkTG//////2Xb5AnMIPmQDGi6z1htfggp53i/rU5k4QwhhL Pijt+f/G//Z8Cn9Hw2p2uZn+Xa5sWs1OG+uJcY78G/3///H2Bnx5XBOxTyH1 VPUrYn2kY3C1qmJKkf////81xphmgCJYj1UseNhBsToschBw2++sZZJ55B/1 8Up9aP//v/1r8ObCdG0D/hBQPcVA2puiCQiIfQH5MsalB3QZ/////yzzzqgg 1t6NtaZ+b+WUVkdB2Mzu65/2TwrhJu46WbRa/////wNFcfefCIM1oJJWov8S blqAT/0u9mgrofejOvwzPL1H////Fj5I2IZV3yvCbAuEH4bYF88F6dT96+Xa 9f////+hrbxjTj4D84aEHh7n0p57Q6G+O7GfNOqKWdtZY68yrP9/4/9Qxb4p xeUE6l/+ATx9ynbzwUuLfzwbWAtkgf+X/v/MNURw3fAQMkdJhLrY1ICsAegI azkRfRHv4///xv/3PbC0GEcxMZ+Mpo3riFK04887phcSymcPrf9vlP53R7TN Hji84mhBmAEJAw8BuBG0vYX+//85DXVgIRvtYRS7iLJmVZTNglXPoW4Zr1Ib /f//t1KkKhBLsO8pkC/vYlApaa90pZZtp1UP8P//29J96DaZFuBspwy8RleC 5es2pJZ8oOlij////28hOTIoQ36rw6mOIcD5IkMjWnL8JE9CKPpZgM7E//// /3Qhy57uVZgUT+xP0SKlKLEFuTqYE3p/UcloeZ2OscLs/////xYkXoNWJvNQ TKd4NHXVBXW1Dk69CXf5MeEfYPt01lXR/////0jdaelwHJqtW/D5hkbLrUbx szphraBmyvOxr/m2lAXNb1Xg/6aMfk5TrzC5ZvjhFC9ARHj/////foq25q+o Tlze1i2qrK2vK4XKbxXYKyNRO+zdyc9KQpP9X/r/7qyqL/BvIXqM71BFIQVz PSMGCCnluqlQ/+1LvLnSY25L7s0oqqGSOHtOAwnze///////ob82tDW5QMoX 5YUQqUXkhivTfixd7WwKvnDHjtCdbH+j/9ZerXq+++Tu2Zjo9VU4Cx32k55f qMH/jKdHHvqI6NMjVHki9aqFDv//3+BrjRKHmvBIfnFhQC0d4oHgs/Of3rmb noj6/3/79IsYjPWoihpgkwpk5jsXmAkeP/m0srpxM790oRc5NtNxY5d9utRQ MEIFi////1sSTGuvvtvbAHsyGXXAxHxLurRT5xZDowjA////f5ENOMh/8Ywy J5MbdgYixgihMFog7nv2H8Wvkg5h1///Av9yP3UPPAVCfYd8ANJiMbvQaoG7 Vu7sYVn//7/1TITEtMIBS1gy2pMc+MfzY7idf/9MG69Vc6b//3+J3FHX/v9j q4++HctN3vnl07f2HOw+n/qx+////zFlekI6W7YnjQBQy+AM/e0QleZn9oX+ 9I1Zo/3GCf//LX4lynoIe0nG7LWxsUHnPA3QFmtwfktr/////xs+2k4wqusL m6no0hPRtEQG67w2iNApuqVeUf0knhJb/3/r/2qjpLo6f8YgD4fJUExe/GTO eX+ttXp5KCm5/////zVJqurIDMMtSmJPNN9GNnhbkdG+RlAxhtWO1UpTufUn /////0aqGi2VSgv8m+Yjoms3BtithWA+HwPq1MGxpJqTj46Q/1/4/5WdqLbH 2/IMKUlskrsvSH218C5vs/pEkeE0/5d+qYq1ngBlzTgniwJ8+Xn8gguXl/9C //+aoKm1xNbrAx48XYGo0v8vAdENTI7TG2b/////tAVZsApnxyqQ+WXURrsz riytMbhCz1/yiCG9XP6jS/b/W/z/pFUJwHo397qASRXktovjHP3hyLKfj4J4 /////3FtbG5ze4aUpbnQ6gcnSnCZxfQmW5PODE2R2CJvvxJof+P//8EdfN5D qxaE9WngWtdX2mDpdXXCh5OitMnh//+/xfwa1oaw3Q1Adq/rKmyx+USS4zeO 6EWlCP//W/xu10OyJJnKCosPliCtPdBm/5s63IEp1IL/////M+eeWBXVmF4n 88KUaUEc+tu/ppB9bWBWT0tKTFFZZHL//43+g5euyOUFKIKj0gQ5cazqK2+2 AE2d8Eaf//9/ifv+IYn0YtNHvji1Nbg+x1NTVlxlcYCSp/////+/2vgZPWSO u+seVI3JCEqP1yJwwRVsxiOD5ky1IZACd8b////vauhp7XT+ixuuRN15GLpf B7JgEcV8NvOzdnOlF/j/0aByRx/62LmdhG5bwjQtKZ//////LzdCUGF1jKbD 4wYsVYGw4hdPisgJTZTeK3vOJH3ZOJr83/r//2fSQLElnBaTE5Ycpc40OkPH PnCF+djWqf//W6JCbJnJ/DJrp+YobSBgTp+DKqTd//9faMQs/27gVc1Ixkdp Mtxpgewiu1f2mD36L/T/5ZA+76NaFNE8NBrjVFAl/di2l3ti+H/pF6wpHBIL B+0NFSAuP+sKhKEHhP///7fQX47A9fsIpucrcrwJvcwCW7cWeN1VsB4PA3r/ ////9HG6MajNSkMhKg9pcAJjOtLilKlpeUWJvnwlhZFVDsH4t/7/7R5TtUTu 32jxRzKWf4wdW8glqXzVJrP//1u0gNK1BGKCbhyK5Eyi3QBRuaXpLv9/i8ZL cIdXPCdpe2iJlaKAnebr84n/3/jbf21bDAv5g+gRI57fC0aEaDFQmuc3iv// Df7gOZX0Vrsj2m3hWNJPz1LYYe3t8Pb/Cxr//y/9LEFZdJKzmShVhbjuJ2Oi 5ClxvApbrwZgvR3/Fl/qgOZPjpwRiQS6hw6YJbVI3v////93E7JU+aFM+qtf FtCNTRDWn2s6DOG5lHJTNx4I9eXYzv+F/v/Hw8LEydHc6vsPJkBdfaBPG0p8 sekkYqP/Av//5y54xRVovhdz0jSZAWzaSwCwLa0wtj/L//+N/svO1N3p+ApA UnCRtdwGM2OWzAVBgMIHT/9S//+a6DmN5D6b+17ELZkIeu9nU+Fl7HYDkyb+ X+r/vFXxkDLXfyrYiT3oayvutH1JGOq/l3Lo//+XwBX85tPDtqyloaCip6+6 yNntBB47W/X//19BzfkoWo/HKHN5bmMuYyx2IDAuMSAyMDA0/SPbb5MxL3h4 IAI6IGFuZHkpAHu7BRvMAi0MAAUcADkJzhD/mQ8BABAACQAS1wMHIX77ZnV2 enRNdi5xeXk3RmL9v/v/c2dqbmVyXFp2cGViZg1cSnZhcWJqZlxQaGV/+f+/ F2FnSXJlZnZiYVxSa2N5YmVyZWJ6UXl0M7f4LdgyXBlDanJvRnZrRnq6v/32 Z2tGMFNnbmZ4ehcucmtyAEcLWis0BfYjZ0V5l5b/9r9ub3RlcGFkICVzC01l c3NhZ2UALCX7mNsPdRIFLjJ1OgSKbnvPFAYDLy0/K/tv/29DZWMATm92AE9j dABTTQBBdWcASnVsA7a5261uU2F5D3ByBwNGkLe/XbYTYVNhJ0ZyaQBUaERX ZfbO3bZkB3VzTW8XL2FiY2Sf+8Jv/2doaWprbG2ccHFyc3ROd3h5emf2//9/ QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVobte3W2la412NnVAJQ3Oha4bYI cA5xRiAFn2ocPoJbAHYajmFoeHLd98K2PZNi7naaXyducHgPoXD4t55iZ3h2 Z0tDwwdp3y78fy10dmV5LTIuMG9xcIxfY05wdXJmmaHdCjNcdmkLRDvZ1r5t SGRWLVHgeXPnnvv+bnpjNQB0Z2FbXymPgll27nNjXwdwaS7l3g4Y21FnMCNY bvpuXEcr3NreW2Fmc9UACmhsoy12gVd8LmRsbLPdUXUmbsnK9nlfQQtkGTB0 TrDQatwCd28P8Oht5dYcztFrtgsHbGn8/Nu+YZd1CWUHaW1teWVycjMNbeMb bG4EZA9F3i7wY2wzZGk4YnJl773lt0ZuPgBhYz8X227D1xo6aBd0x2ZyBIXZ CH9TYWNrX2mvwStE/ms9D3NtaXRoW0PeK1/jbQdCAA4HaIzs3iZqb2U/bmVv L6+1ztTxCyVw2AdnzT23tW9uz3k7tksVvffGGmyPaWTXGx9i3c6582VvT3NL BmV3HIWCcy+u2iLmtc/w+3dpsGtlzo9pCVAaK52/bQkPYyNHdg+uF/O5AEto bmNjGO4Kjm+qI5lpZmnNrT1dO1/Vi3ZuFVDvrbl/m3VwcG+8IcVzb2br8E5j DS9ta3Boz9e9b7p4LmIPZ29sZC1QeGO8JMOYYWZlJUNiNafjMNhDo3DzdoW7 aK3QWmeLBluvgjl3WCtkDycfaxBbttaliR90aUqMksHRN3S2K58b2OG1bm0V eckDWkfvew7Db3rBBnNoMOX23msHXQ8Wk3dlDGvtuWGeNOAIDBa7GTZbcGw5 M2Zvby9b+MKxhwoKw19sb3lHOnOW2s1xb3oV4HV0/9ouvrZrMTCkMHJkDE9n 61rB0eI+7VLnY5gbW6AQWplvB2kjGk6NFvYNN+ZujbXm+AdzooNWc2bYTu0r tVRpQWIHYQqG5s63dSQSV/GN0OL0Sg/0+3I017auFzlnq2e7L9rgLTkaBWN4 Zlq6nqFgYx+Ady9kjhjHPrNoT25pE50jt7Omazp55wo3b28uYm72vW2PV3YP CJ/m2sHRiCpLh7NPhgiN2XkHYTw7OrQfDdVz+3JsupPbJsVY/G8vvwx06htG rBTd+lsnL9CadHltn4iXLl8hO7jvewsHQBNi/bcAtBG2Wp/Eeutw44Wy7zV9 dQsjIACBfEVGbigAKab57lEgAge8LUoAAbiSk4N8D7T8KrBAmgEZrAOopBuQ ZgSgBl+YhS3pBgUPkLHJtoFdAgsMAQDNUthgEgEAPZ2qbJEfACZulByHLW1w BztEdx3NxmNFKEApr0BAtyAWCMUwu19/qX0tIgM0BGwgU3Z5ciCWSl+NQftP dxBPbAHzxAeLYmj3dN8Ugzb5ZGJ4cceL/NSieX7Lc2h0Bv+/NXZtYi94SCou KgBVU0VSUFJPRknFFgv8TEUAWWJwNSDVZ2qV+LUWYXlHcv0bw9iw6FogmYJm Cv///+Q6XJYwB3csYQ7uulEJmRnEbQeP9GpwNaX/////Y+mjlWSeMojbDqS4 3Hke6dXgiNnSlytMtgm9fLF+By3/////uOeRHb+QZBC3HfIgsGpIcbnz3kG+ hH3U2hrr5N1tUbW//P//1PTHhdODVphsE8Coa2R6+WL97MlligEU2WwG9P// Brk9D/r1DQiNyCBuO14QaUzkQWDV////LylnotHkAzxH1ARL/YUN0mu1CqX6 qLU1bJiyQtb/v9D/ybvbQPm8rONs2PJc30XPDdbcWT3Rq6ww//+/wNkmzd5R gFHXyBZh0L+19LQhI8SzVpmVuv/////PD6W9uJ64AigIiAVfstkMxiTpC7GH fG8vEUxoWKsdYf/////BPS1mtpBB3HYGcdsBvCDSmCoQ1e+JhbFxH7W2BqXk v/z///+fM9S46KLJB3g0+QAPjqgJlhiYDuG7DWp/LT1tCJf/Ev9LJpEBXGPm 9FFrazdsHNgwZYVO////Ai3y7ZUGbHulARvB9AiCV8QP9cbZsGVQ6f7///+3 Euq4vot8iLn83x3dYkkt2hXzfNOMZUzU+1hhsk3O7f8XFiw6ybyj4jC71EGl 30rXldhh/////8TRpPv01tNq6WlD/NluNEaIZ63QuGDacy0EROUdAzNfrf7/ /0wKqsl8Dd08cQVQqkECJxAQC76GIAzJ/v//v/FoV7OFZwnUZrmf5GHODvne XpjJ2SkimNCwtP////+o18cXPbNZgQ20LjtcvbetbLrAIIO47bazv5oM4rYD mv/////SsXQ5R9Xqr3fSnRUm2wSDFtxzEgtj44Q7ZJQ+am0NqP83+P9aanoL zw7knf8JkyeuZrGeB31Ekw/w0qP/Jf7/CIdo8gEe/sIGaV1XYvfLUoBxNmwZ 5wZr/wb//252G9T+4CvTiVp62hDMSt1937n5+e++jv////9DvrcX1Y6wYOij 1tZ+k9GhxMLYOFLy30/xZ7vRZ1e8pv/////dBrU/SzaySNorDdhMGwqv9koD NmB6BEHD72DfVd9nqP/////vjm4xeb5pRoyzYcsag2a8oNJvJTbiaFKVdwzM A0cLu/////+5FgIiLyYFVb47usUoC72yklq0KwRqs1yn/9fCMc/Qtb/R//+L ntksHa7eW7DCZJsm8mPsnKORCpNtAqn/F/j/BgmcPzYO64VnB3ITVx6CSr+V FHq44q4r/////7F7OBu2DJuO0pINvtXlt+/cfCHf2wvU0tOGQuLU8fiz/v9/ od2Ug9ofzRa+gVsmufbhd7Bvd0e3GOZa/7f6N31wag//yjsG+QsBEf+eZY9p rmL//9/4+NP/a2HEbBZ44gqg7tIN11SDBE7CswM5YSb/////Z6f3FmDQTUdp Sdt3bj5KatGu3FrW2WYL30DwO9g3U67/////vKnFnrvef8+yR+n/tTAc8r29 isK6yjCTs1Omo7QkBTbf6v//0LqTBtfNKVfeVL9n2SMuemazuOzEAhto//// /12UK28qN74LtKGODMMb3wVaje8CLVRSRyAvIFVHR0MvVrdv/TEuMQ0KVbNn OiBqAC5maj1qzdUubRIBc8CBsZYRMx4DIIN0G7MPByAcNIM0zRQKDAQFZpBm 2fwzEfTsGaRpmgDoMuTgBmmapg/cBdjUBRtswC8MByNXSNMM8gfQyAiwSNMM MpiICoBFgQM2eE9SZa0WcBvgm6toZgcracYDBt4CIEVyPZRayQY4QIFWCXXW cgVK8UUQsBdcwG11UQN2LWNGbPRuIyw9ciB1EnliBxO0HTVtb7tweisfbBT5 BUNlAGN2c85xtW2DCM8MZlV0G27yV606PadxbmdhtMBkewcXa9sASnCsdSZx LwtoekVHcBvEazZ6hptsbmILQ2gNpfphCbVGZw26GyXnAu7Qqe736GMnt+v3 YKEH3/1jVyPQ1lypGBAKBE1raqHW4CCX8XO9acUKcCF3IGYQqy4g1qORYNsP YRttqCAoagNXaCDvG89sWatHcBBPJB6o0UYq/2lFZpRr3dasC2QQaEBShda6 wHjNIA0HZZprTbVlXxt0ERQOu9oK0C5YCHQ4aG1VS9lzFlZXPO21hc4aOiB7 cAI9nfa3dmuMRzctPxdBU0NJSSAUBsJcuXI9aXQgCWau823r/09hQSEwMTIz NDU2Nzg5Kx//Jr0vQ0IHSy1aRjEta0u1xkNlQwLpOqUH/LLYQrx5GxQzAAli vIXdAtpkmT0ikiI7rXDDFk5n8C1HbLsheKNU43poeYZDmy96doT47d1WcTth A1pWWlItWFzrltoj0DATUfsvXAtaz39GaJSSDt238d0LR2IVU/Z6By0APfPT vbVfagIuM3UENDhYLmGHrb47Thh09s+/Ya21LSsD2T8lZmBpYWSjeWMXcAqt Nb6gL64YFy7tDO06v3qsCWEC2mYijc+CgDRnLVJhrdk3motxvkE4ZnI2NCLh Xit9UXZmj9xRXqd3Wmrji3UEUCxFNiFgVA+ftNe2p1cvom5qQEqcEW0rTW1n P6ctrL3ILsU1Mp43b4picEK3HUd1miACbpktodGC9Jog2BdmmX7Yh8Z162cu lVFVSVT6887NpxIPREFUQUVQQ0dv/dvea0I6PLI+D1pOVllvRUJadue3ZBHS VVJZQiALUlXVgNdLVG+7OIxmLfDLWtUgyJfbTkYDEE5w0GgMGmzXWqPgrWVc D2aC9bXFe+dlNW471gFnu+VheQoAADELhnjvHXggBxFjfzb23nRwCCMHeChV i+yB7Pn//8YIBI1WM8kz9jlNDMZF/8d+aFeLPVQQSv//f3WB+bFyFY1F+GoA UI2F+Pv//1FQ/3UQBuK3ErYvi0UIu4UjRLv77QQGMjVBiIQN9x6LxpkGYP9v vwKyA/bqABVGO3UMfLmFyVt0E0Mlx7EPX17Jw4EsAfrGRJSIbyLsaEwkie/+ 7r/ONlqLdQiLHXiGWTP/WYm+DCOJfQg5m/tyawJD1P51DmgYEkkV22yxu3Qj 6wxQDg1wgL0h7LrZ1jlxKiNsFY2N3e/Z/0mAPAhcdA4ZaEhu/9N5UNif+GEr 01dogGICV2oDJX/TmSANRGiL+IX/dAWD2zaTdX8jXGSD+BE3qPL2bWH/FIOh Ag+MVEr/60EvYtugAgAEFKJzb7P9KNyDxAxXL2DHhtACuvdg5mwKCwJSjUYI VrKzx05c9wF1FBJYOcIbFl4tP1tAjWwkjEILL5nkiABgfXw82y1s3S8fiF1/ vjGAHnAnGZvu/848J1NQikV/9tgbwAPGWQSFwJt7/+10Vf4TgH1/AnzVxwec OCpsMmW7v1A3U2gGOFNTOhRhZls4dQkAcAwAQ8PJ2t3FoIPFdKMZ6+3v303y doPsQKbAaKRZDllQagFq3WYzDb6ABXwtt3/3HuRgdGRAJTQC6Gi02JULyzsy zP3maAQ2HGb7DlM8kJzDXLzhfhH0HgUQG3WJRfzNsuG4izVUSl1d0BH+DiU4 nSEPhKmd5EAOjNBN0NA9O6y71qFQK9YIaiB5BuPUNoxTXFPQZtzxITvDdDJI dC1QJLNCsslwiAx68GG8Iw13hOsQGIeHPZMxD4UZDCB1D+bAcP0zpE/QLnkj yWjIQFBowDU9dGw8F7UQAL/+UDrao+kux2hN3DEWpYNM5hoVAXUtvcI24eF8 gcZ1Vi7iVuCGGcO5XCUNCBYXI0ZLlCYbam3YOl3w8ZgyUMgFJLxwhM5sEpTX 9DvEdgUzWLbWfhVzBAYFEvjwJrms0SYqQfjw7OVARhT89HIaNmfhdfdyEudc N2jn/pxy4xyM7m5kBF6c/hjvGMtXUF+InQ4aseQ5cpyAAZxADuTjYSCcnBNG 5NkNBCUSnJsjySDAtGMH2dxmMNoI/htfVMC/2pZsx8Jegf/8AXc2x9KlGPQd Qfzw/9+1h/DWJuEyHQ+3wGpMmVn3+YXSYQ/2+3UTxoQ9JQ1HCArrGiT/sf/0 mbnvdvmAwhCIlBxH/034dZs7+5ubDdh0EmBXXASMYE73DTPTHvvo+Hp8u9zB PBFqRDegX1dTUaBwa5RLS6dN5Le21q1dyqBRCANTQFHhzNV2m5W3OCVTZtbQ 1vRkq1+RqBBqoOQOek/o3qRlCNZ2dA1wNTRNSRz2oMy5UXsHZnMjDbBBVolG BHfSI2ywKp9KrDM5Plkf47a13VYSK05cCmoPdA/BaO0CZfyq9z0gBuz7+xX/ HSleBS1qWSRFL87AyG+EFyzTrMgHbnKw3TiyBEzDP9lcEyYlZMdRLlZWQXnc Hk4/WcQDd3ERxDz8Xs1CwfwrfGjjwxFMk+AoML4oSiwztnuNffClAL44C+AF eMC0G6UjL62gO7QwEclNAWF40OTmuFAATNSEZgbYgI4cOXLcfOB45HTocMiR I0fsbKRoqGQcOXLkrGCwXLRYuFSRI0eOvFDATMRIC3PkyMhEzEDQPATH9nBS 1MQIGwucPVsvyFIIocAQ4zxN9zYj8Im1BRK4i/9Lb5yN+wJ1BbKYA8j32YvB eQKb41tL7Gbh9AZ2Bi0GAMiufbdm6fJ1C/L4GPIMu3cvtQY+zrk4gH0FuTQG ajzvW2j8mV73/lJQ57FRBfoE0914nvjw8laFoAz2MOPjzfTUaAwldgzKt89w sWcwslyjsIEEw6HpPfZ/BWnANU5aAUARZqGyF063HtIHyMHhEFkLwapEJPx3 //8EVusli1QkDIvwhMl0EYoKBQs4DnUHRkKAPn2LWy8n7zvyK4A6uQlAigiF Hlu6GnXVKF416wc6Gfu77ewIdAcW8wUqDvbZG8n30SNX0ie2R/X1EB10MZD2 JdfdDKqLXQz4uhAPtjgCHfxB1wNmV/3WWUMcWUb7vcCLTQTBdQ0zddhjmkDM bSBS6/ZJFJu7xNJZXU1EVQxDk4pW4vbSAYSKCDoCGEFCxFDRTuDbAQIKK8Fd cCR2aOtvbGkIbol1+IA/AKNIrUO/dc73PiYPhTG1JL+AWbpGDSMjSUYPvgQ+ f3PPFzcRWVwOiEQd3ENGoP3W/oP7D3LigGQKJck4TdyJfxvfYvte3C8QMQyJ gDgfTKMbOfdK0HXwF09aAUZZC5b7fQ+OzgBUahQoY/j27VCTnz1dliBd3YgZ QUf74usWuNwlbAi0Z6O2iFANKch9a9juPgtUi138ICvzUK70bHh5Fnps8PB0 USsD8z8I/BvgHD6NNAgD9+HPK8s78xu/tW+NCAFzG/eFfiuLwysxA+0btW8v ihQziK338Xz167vu3778Qf+FwHwPBiveQBkLiBFJSHX3ZuFbGAYoGVANjQ95 WHCfuXS2nvgtACbloGO691umJpCRSRpnGPwb/IUHZSWbVkQ3AYsdHNkMC87E +9Nc2+pswRyCcRgM6ChDMtZR6FkgyYC//du3ZTJGPEFZKOl8DDxafwgbyIPp N+sf1tqxBgcwij8cGMCD6Ggo/TsHMMHgBJ0KfBS6aVtJCEPp2eiITQjB8EMo UU10QQPDSUPNT8JCSzhGzjvejUQR3PAXbot+ISWKDogMM0Yk6xRIySHNJzoY K/MO6IMMSTMI6PzntlI7J/xebTR0s72z1wQDPAMS7TjI9OUEWThqBr6k65WT 7t9PfeTzpWalpA+IyPvTbXOubOQVUKTNgVlZX5zqSzt4XnQUyWoaBlmDwA3N fq7f9fmKRBXkHSrIUCehXMizJVnIyEXdFtxtCARWi5HSfASKBujS/zVeDTQ1 34gHR1lGY4AnyJd6ZhadRFYvvGjcJZqfrg68WY/Q8IX2/s0hnVsVFRRYNHRZ Yki+LznAVlzMU2+wBZv8OVH/0GcgwAa3A+sDiFiUcJ8tzGiQmIQmQT5bzL1u E0gX2HwmZittw1l/+IQV+JVOTBLpHBhsDKsZnUNTHWlidsgto1MOqTSQ7cX3 AFJTWCQMMkJjZi4QAHD49tB6MBnd5slXPbrQGnuNvUNP3/84L5J9C9bYUw7G BDhcDDxktuobXBV4kPjsTEKX1yIHGyH2hP7/NJWQEa6EBUFC58J+Nh1ZaHgm Ogawl7f/O9N8ToP6AX40BAN+GgR1P2kZbPdsdC5ocAfrPRRsQQZ5BmgoZGaQ QZ5gE1xYEq7ZYdDXCM5Oey0LM4RkETsDmHpn/Ap4GQajZ7MTy/NZ6gDwCvB1 XBBGDD2DAbnIAPwM8maJmK4tjRZmWBRzDAI23YYCMyQz0g4EOBeak+3cJJ0G BggKdPilAjfBNDsi3esJgPkufgwuNUjRDDjHyCrLiIyxpd8V7SJCO9h9Hiut vA1vpS/wi8gD2OYUwekCfAuD4QPccgH3A9DzpJ/3Oy5DBvYrtA2jrKzNfYCk M1a4VSLeLnINFXOG3bbvhDWnRqRGDWoQD04Y7CbGg8YC2lYzeIcWb/q8yc0P nsFeWDzEreMTS2X8YPDoQwSCm3ssCnAFViR2NdUNHNzPfTBf/gQw8G/x1uYF UAXrDpxAfQaNdAYB4Z5rKwoPBoU4Mbn3+tYVOQx8y4vGh1hZoKFnKkPZYJ87 aFvN36h9a4H+/wBf6gNV3m6NFwbSdEo2TxdACX4LinXjL9ATDz5GQEp19ck+ LvmtLLEWJ538ZsACiUX4d+pUaQGT+2qlEu++9iX/PwtUEgR8pusL0b61fYGK fDf/LqhOEX/0gCQ52HoFHEC6A1d3jK2rkgEa5zAb2BDlM96eJXjU9rF16F4b oqkLuChfHAxYOkVti7dWgzwC9H0HHekWIQyFAmlFU6e7xX+q3hU574vYWTt3 WXwfS2wXBjwARgoDTjbBYeLSbTX4CAY7x1TgXBcstOD4AzovvVwDsLXSRhRo A5mlbxn6XMPa3LYDyq5hYDpIi0MK3tCiYLo1nAKpu3u3k6FDZlvgQxIMg8MG DqBhF6ziDQrkQ49DwF7v3oKJXeg+f2G+JEb6dG8TYtzeq+x0QxhXqHHsYf2N tZVFWYuGFr7oF+QQ2D/sTwu3jcKDICzGBQn065ABjscAE7pVD4wibjx0qQGr jV/Jvwwjfq4nR1NVtm0z7RiHtR7xVccBYX3YCiw84TvddTw+unQRjYPboa8Y YM5W/YkoNcKVayT8IX6b23izCBCJbCQUdIsYUTmnv61zCw8YQGhV6wFVm/gF c3/ZtCREEAbVON5EwTxgRl6O221318gh1104UFUKPFUGbdAOlcfEX6BA/OzM 1lNESWQxjlwEVVOf7dghG1XIU1emaOiFU7zZuu0vKCc0O+4Phtq8tKQmDgJG V4PmDzZqbhubA8ohAf5TD2uYW/cgGoRfiA1/mYvtY270fWU6+lmJjSSqFbql G9+SIRwDGBGmeMndsRDrBPzhg78KJlmazmw2nw0ID5HC17w5DAMPgoO9GVX0 x7onRi52FVbVgcdSx84APtuLBz0YWwZ04Qg8QChPKMZbtxaNbsGL/UCSRUj6 1kErWXUSVkO6Lrehv/YciawmBgcYm3P8OiEwrIs/YgeeQdL22x4kJSBH24MS GNlyIbrtHv8PFAoUvCX+2VOM8A2LhLbH8VNlumehC5EkeWxEYQ0/9WI0YEsa 1V1bgROuWI/Ed3tvjyvkXKZU+XLF4uASXZ2cFhECEGpkjNqGMahGkXzWPXRz IQcHvrh0F+ilcs3iIXOker99m8XbJg4QdQ10ImisdouTzioPzBJf9FZ5leuB hRwPbdBvVztq3VjrcYtDwzv+MO2ocHh0YVO7k6ZPdUsYckpwUZk+Uy6QwV2D Rxy0gw5o/y6yEJ86dxjX4FN3I7gDk1VrP6D+dabqbhNSQhxgvpyiV7YpThoD 0AUyB1bD64S4Y+KE0QBryJbZ6rXsxNAcLLIFO+vvHaS+AEBB066exqrL7RRR Qtdfhh+NtvArXiGBVIXrChtw92GNdwTSWGo1n+TSdrquk6JWnuaAEQrjkd3Z 6JMVo1wRKItAjVcccFtJABuzIxz8jFEVaOQ+xFkNM/SjC6kGXHWbMZUBDBEG 1BkP5F3f1zEwBDH6LQVnPwxl8IDIXwlRNqkfLTxsqvhXQIBHo9vVA4jAQEBD dFneYLUrj3RPRCSz3UEG614kDyAvig5oOkm1gtT2HHUbGMj2kbB1xesSGcyX uOW2I0YuEXXn5Ylc5uoNTOhNQHQ/aVBVaiUDFG1g789g6gwEK0NZPEr2DAvd vWtAlDOIdk/BqrXE+RArDVA2IN1G/U7AKz42F/YO2SuWdSojgyvt/3YkBlwr QHUDS3mvgGQrFWrQSriLgb0Re6kB27bVPj4GPRP4PEscWTwbsCuAtJO9S+50 Dy3LWUO12l7jNSu9tICzutN7wLZfIetMjTwuKAe4OooHt8llsyMnIXgHU+Vu G3E/tE55sXWRujY4WuR8Ct5AtLxwB4YD7s5dWcPvi/FX2hoWWg4wgEIn/zfL Do27uyCF25GdhHfLwrsGGYgDQ0cMN9kfA4AjsDtsuAAMKDIREDyNhHYJGofV dBzFF8ZcGeQkBTru5nFroOE1HRIQJwtWNpps1L8U6VxPD4i/bdSURlW1QF3D gyW4vYXaVnhg+WyCBQsu0TgYZO1TQc45HVZmw/0So7wEATk/oxcWCC/rC0wH /5YNcEvuEzzfHBx7uwevYyp/5BBbKIvLvREt3isNFMSNo8CCu83H2kmM7ysE D4/mu8gTvcAzcMN3IlOLxYvPWkMRWZEuA8vI87yBnRiUzO6RQb4ZBoMqf34V z7bxbu6AuEoFCQjHdGS397JnkYoNYfghBdFye9uIRCC7MHwL/Tl/xRoOD4qI wQMA5SMN+FvKh0ihGWvAZIe/jX6xVRWCDH7BPQwy65/87YgdBCBVFQZ8CTzr B2EJx2cIRn3hB8nDeSickWpdtwC8Ri81XWDrBZ4PZwY6w6qIOWa1CvkkEdQe slHfx8CEPXTYhKkbVEaBsDl83rcw0l2ZABIXnF/fuA4+OlO3U/8wqRFQw0vb t0pHO4NGjzkedeMzsMkQsnNLK7ARFO8NXi2z+N5Y6/fddRX5qvJxEEH4wlxX arwLoyDAp75Tu2I1d0ZHnqfaM1usmR6kFN3wg6xIdnN4Eie4eK+2NNjA4ORI huAYMzVN3PDwdajtXiDTnX8mqgZo6CrNZiehhPBQLdFkMjcIrYEoRuTIwW4s IWoFGZQpNmSTXE3cMzPDS1jIz/QkuPRHMGHFkhAmUb6vH20N+UtBBDw4FlYG pQ8+8ZvB/OMpYDK1CJOFV70QfyrPYQNIefDoDwPHQanWKPbdEj7E7rHaOHXI 1L2Lxz9FFlOzYNbCsgqVQvEKkAxtjlULsKF+Tdc9Nn8SjY1g4HaHjf0yRxTV mILRbepIY2zMg4IXHXyyxC00ClD26CyLNquClRrdGxoWra0sfviDxw9XfmnY PyxeiF4W61lXhoBmCACrLoYEFIyKTv6aCXuIRglkXKF8aPQqJMQG6yMGHImQ XQ5ztIUP/jef4YB2YSJmNVE+hK5sqqF0dxH5E4SfBsT+zzs1M9Izyff2KSV6 9yPfDyqDQTvKfPHceIPACjAGPbQXdgwx9BBaij8XYkBqTzSAMdvbYUG5MU9Z 9/GigKgRjgX1KBMAXMmtcsnJGd38KmLBIMuAgICBT4OhH3yEWVlnddQUcslC A6sIcggK4m0fNOjTxgOhJn2rWus82+zO+iI5WFy2/oUbTzvzwItWWDtQWHNq 8MI/vPXSUeaB+fx/XGpgU6DcQdhCLnXvSiodJaNTE6B6Jx9CsK7ziBDzs1iJ XtudNbxcf5qJrkB4tjkVsw/gf3WxV41+CMdGXP4fMJNjd+7/dgQzW0DhWU8U V3OvznVpFEppX2f89NEeiZ+ESTBT/0Bc6Kyhja9VOc1hWZwOUbNjI/GoA1UX G0lZMgYp3EmV6DT6UISFhoHxmDnHzi/ICa9KVs+wCd2OFnZGSi0VWWMqV3Vm G9xSkc6IV8Kjb0htaqcruuziigRIdOaGrbuiX7ZXv9Ac9C3cteKZQw9WxkAB 99eg+1R4WQkCCCMAdgcmFImPTPAuoIxuj9SCa0RxRIB+LHUgo24UzuorHGC5 6PTwUnFHZEgFhSg9IBwa39jIzq3+EesYiw4NOGXUlhkPCnx1uNMJvmAHBAyD ZCQ8/S0i9iuixwWFS/avEObrF2jlpFE5xwQohYYH3jgPRn1L4GMUK/AXOgEP lNgh0LDhiDRwdO2gid9ob9/JdE5DgHhEdQ9FcHqKTgk6uML250gJfkgEO0we cvkFtwNuaoeE14H77HwdSTTHBnhLJoH9kn4Qfb3NlRhzBl5ZCKwksEFLbRQ7 xU3zSVsdtp8yBHMojUYYTR5WASdN7mjrWuUYrBa6J5g09BG96WGz4A6yHXEN BFDHZGCDxxwEaIP7A5PiLggLOCm+22cfALsN4D1wFwrKIkhmvt8We1Y6jaP2 o9AE1Ey66mvDwYAzoEJtCD5lfQw3fhb0PBZt4Q+2CYlRWgKICLbqxEaA7S5R DAewRQFlroyx7aj/9r8ILCFbiV34O95/Zi3GK61QIRodDCHLxkduwHf8YzKj Sf83i7Sit1K4XBwZBAPGurl3R7OLBx472HQjcRMrVa7bDTRwywwzA0kr1ths rd3+CYoZiBhAQXv3i2IrWwE7R6YLaItfDjx0dYkjXHcFXg+OdLWE7cNSmxxW GgYeMx0pCzTK3fxWCDSFA/EhQoPBwhdbXgdbSwiwmY040n1C1ku5u1M9RI1f AVmCHoW3pov/w7OFWs9+Ew4X3EKlRLeLkO5uBUku1Igbwn/tuAl9I99aZ98Z FDCAuhgWQ4N87esOW62adBQxtcDIuRX+/3zujVEDO9B9ZTvPfWE7wWFPXAbv WhtsuyFIEk/iO8J+Q5LhHfw7x34/K8GM/wd8Ni055hYb/QPOO9d9owGRFfi1 YhfwQkGB+gRy6fYhDTzoEA6DAA7VXPiL+zt9FowxXgRMPZTH87gQAHV8DxdQ zgJyA2w/LOBEgE9u8A+ElaaJDJMA52r4Eoa+RStTUb/9Dm9vhluLKnJXUSoC 9FDrFlr40E49zHNTdfgiBU3Ae/EbvgYf41y8rAGODk3QzWjjN9oo9NuBffgA sN139gXMuiZTMFfwU64B16qouPmmDojVgUkWX4RZVyYjv5TMVs1tPJhcfB6u ZLYIzbPPz/7G6B00a43mAjMAwgzwkGWQbWj7HGCeswTfwwRXJAT/vPuNW+E7 +61kW+vsR2SLT2AxFtvYfnZViU1wNmw6cITKXeVg1eCETWgH8fwv3Er6TkRz wRQ+iFQF4DgcPrpbtQDGRiFy6D8MHPwPwzG5g0VwRP9NbIK2IJvZcPz8YAlk w9ZuTHPrCLWB7gnzUBMIXa1Y0FhC/UWoaMAt7PuEGgSiHvCogXKJXi91UWnq qP4mVKECkuiEamehmagAk0JwCTWLqIUFDH9vBz1Pk1mam+J9QZDIV6MNN+D+ M0iDfiAoD4KzWZTJ/zhLH7TURixwPfsRcAbAu0CjLA90yEAJAm6wtIvoYX3v ZeiXpIPvLUQxLWoP5ugJrfhE5TQRTH3ofVq7vUQGACADNw2BY7cbuGIp+4dH LeRQjGpnL2hcv3zg1z1t1/sMMUABHlLHJHWjK9EjW0UkLpk5su8xyC0/HBmu OeRIDhSUDAzJ2At0fhUEaD7bQI78LZ4JwBILSR3b/kke9C23FPw2eOfwzMNT 4+wtcAbMnAJKRJP4m6ImHzlGIHc16wsyjNDgFOycrXVYcaEE9Bt1ChiGyV3r TsTBDwJ1CdhPdgSnX3RYXAIMV2wu2MV+DJo7/jdAEjlgpnCOZFs5NcwY3cE3 ix1cROQ6TfWa39MJsuTWwlSzJpqkGTajk2qUFXoR5RgnOTAuaEC0pP2zzUGS VpOS/BWKPBHvUHUjNREkxhNmu5B1AyPU6xHI7tcJMCCorDW90Dzv3GwbhBsI 0QB0rhGbGUaWCdKcD1rF2TfKJlC+VFArTPixLxP2pRB0IGpLKMuuYR24SCII UwjpidggdAanJ7XU9NBYbOlDzfYZvDjIQ/E95FsQKR8ISSI2t4V8/1Au0kdF HvK8aEAuPXiDp4OvYb6ETLuwVkX94RkgCVOUFGe0DvPBHiw8NEm85rNUZSj4 /WElbJCXUBf4/QoZADac41OmTWAXzZYd5qIt1xyyTAzhkRlqBQ4HKrOBg6TT VqwqUMLiz+mKYAGbVr4RAdjeE9SKnQ0T/XWke8nqLuAlaQ9nqxAbxg5n3fwo VnSzMh4rMPTZjDcamAYiaKAf5UD7K8ROWf4PGgVafLerPNno3RlQoWr/21AA EfLLDaIjVKRVlWgAgNDCkEvWCvoD8CJSf5CUFj5wCwsIuSf31gG1/Ze6AefH U8FOi9j3240834kv9Je6H4oaSDPeI9nB7wQ0nXBkGWt33TP3QhQS7jzbILLn /t8lEkiuOsNCRF+yw1uEwI/8/haKAjPGI8EhBIXwQk916g6E4gse99BeXf5M 32/hAG4g8M8HcggH2sTNDcQHdt7w1AcBcgcnXWEJ5UUT9vZjKdORH/YKVcFN xNnaRnDAxJcLJAUFraMSffZmiQENqvwPOEfflwb6ZtHpGMG7GnbpnAQNCGpX VgAdehqhGEikPQPs+tQWWruQ6x1KdDF18YBe2NC1+IaJdnaLVmxgeHgDl3u8 Gd5CenXLaAkbylEnyhyhT718c2C/gHEdaKwBWeigVtPJ2ppqa/iu/VvGB/Us g2yuwCQCQAye5faoOiZ99NH+bE1VCuCyHpO4OWQ7CC9qLguIFkvEFmTYCcTZ UK40bOJLAwRtwlBGvAU1TbeZjsG+A5DAkha5VtgvV2lGJfe7ofZ13ZQKxAeW F+y8Xc1ty8IJMMYCmPG3qG2uodNmyggFnAtti0El/L8NzhBtQteVoDrSA6Q3 g+aLBW2tUIJ41GvuubamArIWHjwwBSjEDBVkDVQQwdFb5h5mu1swz8Kznx87 h4SErDURa6pQMQcBJmnTcIDYGWGl+J3jZCEb+MA+sui8gsFUMS0yPPZsuCwd iAECEowUrAixwkzRrsqZortsrVdFNdgFBi/cZ0Pb3csBLgfeK1hd4AErnGzP 4gHsa+TYkqjoEKE3BPI/lhF5TvvGXjoA/5QDEwVXQ2oGU7LRI2YvufbqTuDA HOFmhGbqUIH7OGRz7un4z/RofmYEgFbmEUwFn2g32+sYDVA9RycvPBpqJLbu rDKiatwIK9dUVZRy/3TY62s9MyNwV5SFohu2/UJvA8e+BuwNRgGUiZ0MANNQ bCD03Z3WAV8wUUU//jo3s4aHCMFogilBUvbgZBB0GLGwnOiAFhMJYhEMfyfM JRQQCpFocDIICUxSElmHBKcqGGEo/WLXpMIIZoJqCOBmPxtKWptZdO1Jydwi 9mbk5JuTRBGwCQ7A5SCL5jerd+u7hqGHbP/YYkGSmMeNu5MFWx381VOw9Hhy q2Yr/1wR4Wp4YBgcFNoFAi04gIW8DKCPUKZjVVcU9EZqP0QLGwvR8l6gjXdQ DlB7suBS4bRraE515UcXaoSfRVuwKVOHCIOHFRTqwwRWYsZk6CbEN4P6Yn1H KpQ8ikvArIS1fjCt1dvIgR8cO8rTI0RlK5pB9X0N78k+NYhciVhXWgMz/1z/ m+z2i/ID8dZ+GRcaFYDCYYgUO/3N1a1HsHznOPE0B8ZGBEA2LgWPI4PgA2f/ NA8TjnJBFshWwYnkyz6y2LgIfUJxBTP2vbIbfPqDxwOAfh1ylDNv//4PAkY7 93zjgKQeCwBf62A2sB5GxbsIw7mor9vBCAPwxNKwTQB18j9D/vrftm9DwEax Hh/JzTvyfQyKDMWwMtLbYoRw6/zFOxa3uxWAdrbFrAuNg1slSzeMhV8y+Lnk gVwyADP4izSfAfyzpFZrBN29NZCBw7cHaFw0CGGs4h/AGDYGQA5kBQ8Ecrtk QAQM1igzgBzIVAwwkOchvDs2LDME2ttHFrQyfBYEVX0W6GT31P0lagHlLHwS FXwNjoAz3RMw9i0MA5nZ3EdXiJ60HAW1Vo/9Nh5AfXuGHgE4JXUhjWyzIteG t1BhNLapSITLuFCAbWy5tGDztfT8vyBXPAcjep+2iJ0TK/T87N2sNPlMP1CI GFM4kS3A8GiIo8hEKxo72zgYKc8cV9QmzxA2rSi17MUu9AZypABki0E7N+DB /BJYYCBmz85zcwGEJ2iAf2hKiDMjDFD8wyCfjI34D4QiGWARIQy3Q768VVRO PBg8RweuP4H/WxTCmY208gvs9iuIACjhYk2CfNGwGj5xPRwJxcwSYgUD9beP dBV+DPcCfwdofDSvVq59At7rBS4NQ2eHJUgJRgdJuIR1RJEtyu1c+LezMwMb K2IhSnQPaHQ0rNU3obNmHDcOfYfiGWgNnw5kjB+zgXYIE7w4J3jCjHB0CT2I tlsnGjojiDC4FIfYYgfAXrjwaigD0OaFaCHF1KgFAAAyctvQhDUgTeAJ5CDo NM5l8+zINHXw9IwpSYp+YQw71n1pyMFTyQSKbsaB9keaXj3JRTwgcjg8PdwA /0v8PCt0MDx5LDx/dCg8gHQkw4paLwEgiAT4MJ+625NGCsYVDUYECvG7gKBu AdskHv9GAc5HxFYqUPfs52MIsXxJSwf15/8zyUH6Jv5busp9CYt0xdhAZfGD fMXQBAm4TdwR1FPGB+jNIBBEEL6QNXK/UDTovPOlgf2kikwNvI3iQvFfiAqK cXABB/8t1erB4QQ/0M4XiEoBikiWZVm6ARgCDwIGXtDtt88ZAopAFeA/ikQF DEIDdaaeJ/UYBFdYAgXIFjwi098paLw6GDXoT2TWBIit9UXx7DAE8De6UJTy znIiO+xXnNGANOjoODmAJrdFOWQxwkb6fy/hsy6KhAUniEQ183W/jVUlahu6 GfQkY2JYDF2IWm+pNfiIkJHwg6hzL7xeTHINYQMNQ2kHCgO69oUN/gRy2aYy V9XYha8NN5kJhXQqTfhsvwtocwTGRfs9CAL6PdfErQEUdR88A96lDJpUKjii taSYWrhBJgcUUVMU2KZNxYVTs0Dxu8DDspFwEJffUAV74TPGCQ9Sai6YNkoE 0HSvZnhXLQtwVhr6yFhZLSSNQwQZ1ZXOdgCqIGgYrnEgEvPFGxwnELIGlRat WbXZyL5TG1AyDH7ZQnbZDjCvaDwgERiDvVQLohhoCJo1lB3Zt8CUFGj4NTPc EVJNxMjU1TlZXSG0oHMA0ScAEnKw1Lg3cMiFWN7+c1g3g8oddvZOUBdQhBwy y426YD91A96uYlFM5NmMeEgsRLg22Qg0N3ZHxlBP2A2wjZ0IUoWLw3ZNcwmK Y8YFE2ZopPRAasD/DB1IBDrRjVnu1zvzHfkGMaGm9wcPjL9vyA+oSAa4+wyN +L1TwwURXNpE5JPtZhQNXZsKXtKNtaHuqBFlEnOLhaL99PGGycHgAka5NAWf I9AWtliKEwrXQNhZiYd0YEB0HhhNie83O2TZCnJl+eAnTE8yFnVu/QFvOV34 rSLLA2r47MMRJUhgJnX4rjqHPxQMRlc5dRC4NeoFEX5yixFEKX1CR22pyRSM +U0kmFUP6tKJg8LVgLdbAewMadINcPVzizpSvOz+iVX0CGXqYdl+JvlYfdeX zBFadBSKBxZHPAp0Cu5qwd+HA8c7RRB8l6UviBwIslT7EZ+DyP/r9jf+WL+B hijDCTsXgD8wdBlu5LCIVxAHMB8KlggDUKVeyy38QpHAO/BX2WMOs0eWkW0I CFoMURAP36D7zY5IigY8DXQMjggSdAQ8CTBbgfh1A0br63QmKoitQCSjyCVG 7pruF+E+PDp0OS41MSoCBBcUf1uK7A84dQk4hA3/QNt10C4QAwRJzogQ0XfE Xe5Bgfm2cr7rAU5FYmysJRIAXcyYLM+FyA+4AP/TIIu1XcwPDiQ4Kxwvw94M kOk4OnVhHjCZ4UT+Ww/ooGfuSLZARtLKAUbpXAe7ztJP9RbBuWGCv4GhXW3i CkI713zqdd3HVhBlAipCHQvjN+4pavA+CqiOKglz7TeICIINdQ7rCyALHNDS EBsHBjUNhIIEDshLnY9tawQXhk6K5x0FBBtsK20wA4ZJAI6SNTPCcsNjDXWE 86sMm2CSABiNG8eFGDCdegVNBrZoMaJgZeMRDmfjBtNQUVBk/JuWEP2CuIvB x2grYaK+2iwUNysaafsAEOoPiF7CgMMP+4gfcAfFVr7aM4rlu99eF2qKEYD6 IMr6CXUTQf6lUm8HOX8St9wEgEGNRELQzRrx/x4wfemAOS11HHlNz63gEFaz Z9V/bklRqrO1VmLeEAxy3FWAaEQ4Skg3soutaKg9G/v2oBdyQCGKWj00BIZq PRAHfkg0gi64bfZAU2h1ko9U/GoGG5mpPYQZ2INg6i0CFy849VfUjw/cPOX6 HvK+mDr4xh8wmF11alToiFZTKZyLfhCmvkSVhZh96nKMxD2QeI253OixJD8K NDiJvxAnyzZrzur+V0VAGHxCMtjuBz0rNn48OCj5PN/KM3RPK49EI+TALhQ7 /QO55JITCASnJI+Q+9cAxOeZzMFo/L4hDLV6fJmRj6rdPV3Nkuk3wPiKAYvZ SjwVBw5SU+lDigM/awMXA0MV4BtfO8t0LlAudRFqzWovgEihtERArHFbDMMS K8H8D/LurdBcTsITy+usKAVo9DeZM7wIoLcLkrWlRnh8I519v+wmqFAtuR+I E/MSdHNHU+sGCQZGU0tDwyh1xqa1NAPyLDTgItxYXA4BSbr/EEwiMDYB2EL/ bC9XwSASAm+XD6ks1W9FERAM3PwtUCk6IbVXWSNy8CAlU0tLRA0JIG9wuhOH O4KxGf3eVkwCuexIUBbUCZgdt6NQvQ0qSE+MvRwBfVM8VHN74HQrahkbYQqy idwIQ95zi3BUlANrQ8bay9UHb5PeSwBODHuM6fR1GLp1cEGm6p3TStMCrg0D JPAnGDgkloJ8X3IDAVsNr4gNPmbscwDpwfkDUers/BgBC+Ts/ACCFZ+GSFxA V25WIHbRhNXrNcHjzSUjT/B0JOwM7j+IlyzsdCKbxyGmHl0A0DwDvqfiBvr4 CQ+Hrd8khURyi3yzDZxxO2lw/hSH7Q6ycLZo2Mfrbg3QhzyHPGDIUsCHPIc8 RLg2rIc8hzwooBqYDjOHPAyQidZjJt4bO+sHgKUNOwZ0SgaE2FWNCA07yAKz sMYQaLIPU3AUfL6g9hpibOc+GX0RRxVt+T7RNN12QBQUgGQpAzdF0zRN01Nh b32Lm5HvTZn/JVQRBQgQzMxfIAzEUT1wOQhyFIHtj/2+6QstBIUBF3PsK8iL xAy9LlXqi+GLU5xQw5IKGUSRAKpUqSoOWaqKQoMDNs1BUagcAUOlopeIm3Rl RnC3tlH0TWFwcMBBEw1uZAv2DEWIFQ4DXqgadnJzD3dFbnZRdRTdEG9ux1a3 d4d1fWIYVytvd3NEHWVjgv129nRvcnkVRCJ2ZVR5cCR272f/R1NpemVaQ2xv cwoUVGk1927fUVRvU3lqZW0LLRwb225B9kFsBmM6VBjak+9vcClOYW1MU1Bv RyXsmaiSIT3a1u2+DkN1cnKlVGjnZBFXicZ+u83tCkxvEExpYnJhpWxeO/be NXJjcAmPSGGYJHDb2sGtQXQdKnU6c0GyW7CBMjcIbkGdQAjYbVAbaEGJClue tdhkHx5MYUWce7rDWhlRTV94b4c2WTtYXURlBmpTi0Bo/1ZHTW9kdRUUGMKE 2HdLVbtddkgaQXMYUwhlcAbYlkt4RXhpJWFGmFPtMPfmDhxPYmrApFCw37Al tGN5BjL9aYLNCttja7t1bEwptVDVzRppWk1JZoDaRfltYeUXA+P9jnBWaWV3 T2aLAGIJK7RMOPO5EQpQb8wNYWRlQ9i/2VvbJk32SEJ5dCJuQWRuwhLeZHJy FsetbllrtEilOBwrJ8OYMXsTGWAEvKwwhG6qzQlpQXePs2GNRklxNWtlZBN2 agulYxILFUnSmWGSblIi5FUzNsGwsPXUQpMmSx2FFJx5orXascf4NmeMS2V5 DE9wTd069+gLRSQOOlaNdWVhBwCGDyQRCTN3KaZ1bTAMr63ZbLM/ZMIIAW2j 7rQ1zHNlomp3QxDz2N8MAwdpc2RpZ2kZdXBwc83NthF4EglmWwg4zVb4c3Bh S0/NLFjA/nubVS9CdWZmQQ8LZ9qOPExvd3d2OXK2I1GYbdh3CkfYLMuyPdQT AgoEb5eyLMuyCzQXEhDVsizLAw8JFHMfyD8WQlBFAABMAQLgAA91y0n+AQsB BwAAfFFAEAOQYbNu9g1KCxsEHgfrZku2M6AGKBAH8hJ4Awar2IOBQC7PeJDw Adc1kHVkhE8uNXQrdtmyyXvrACDVC7ZR4OAuwccAm/u7d2HfI34nQAIb1IUA oFB9DdPlAAAAAAAAAJD/AAAAAAAAAAAAAAAAAGC+AHBKAI2+AKD//1eDzf/r EJCQkJCQkIoGRogHRwHbdQeLHoPu/BHbcu24AQAAAAHbdQeLHoPu/BHbEcAB 23PvdQmLHoPu/BHbc+QxyYPoA3INweAIigZGg/D/dHSJxQHbdQeLHoPu/BHb EckB23UHix6D7vwR2xHJdSBBAdt1B4seg+78EdsRyQHbc+91CYseg+78Edtz 5IPBAoH9APP//4PRAY0UL4P9/HYPigJCiAdHSXX36WP///+QiwKDwgSJB4PH BIPpBHfxAc/pTP///16J97kNAQAAigdHLOg8AXf3gD8BdfKLB4pfBGbB6AjB wBCGxCn4gOvoAfCJB4PHBYnY4tmNvgCQAACLBwnAdEWLXwSNhDDosQAAAfNQ g8cI/5ZgsgAAlYoHRwjAdNyJ+XkHD7cHR1BHuVdI8q5V/5ZksgAACcB0B4kD g8ME69j/lmiyAABh6ZSA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAACAAMAAAAgAACADgAAAGAAAIAAAAAAAAAAAAAAAAAAAAEAAQAA ADgAAIAAAAAAAAAAAAAAAAAAAAEACQQAAFAAAACowAAAKAEAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAQAAAKAAAIB4AACAAAAAAAAAAAAAAAAAAAABAAkEAACQ AAAA1MEAABQAAAAAAAAAAAAAAAEAMACwkAAAKAAAABAAAAAgAAAAAQAEAAAA AADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACA AICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAIiI iAAAAAAIh3d3eIAAAHj//4iHcAAAePeP//94AAB4/////3gAAHj3d3j/eAAA eP////94AAB493d4/3gAAHj/////eAAAePd3j/94AAB4/////3gAAHj///// eAAAeH9/f394AACHc4eHh4AAAAezO3t3gAAAAAAAAIAAAPA/AADgBwAAwAcA AMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADABwAA 4AcAAP/fAADYkQAAAAABAAEAEBAQAAEABAAoAQAAAQAAAAAAAAAAAAAAAACQ wgAAYMIAAAAAAAAAAAAAAAAAAJ3CAABwwgAAAAAAAAAAAAAAAAAAqsIAAHjC AAAAAAAAAAAAAAAAAAC1wgAAgMIAAAAAAAAAAAAAAAAAAMDCAACIwgAAAAAA AAAAAAAAAAAAAAAAAAAAAADKwgAA2MIAAOjCAAAAAAAA9sIAAAAAAAAEwwAA AAAAAAzDAAAAAAAAcwAAgAAAAABLRVJORUwzMi5ETEwAQURWQVBJMzIuZGxs AE1TVkNSVC5kbGwAVVNFUjMyLmRsbABXUzJfMzIuZGxsAABMb2FkTGlicmFy eUEAAEdldFByb2NBZGRyZXNzAABFeGl0UHJvY2VzcwAAAFJlZ0Nsb3NlS2V5 AAAAbWVtc2V0AAB3c3ByaW50ZkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ------=_NextPart_000_0005_60A29288.7CBF4122-- From luke@REDACTED Sun Feb 1 14:43:23 2004 From: luke@REDACTED (luke@REDACTED) Date: Sun, 1 Feb 2004 15:43:23 +0200 Subject: Server Report Message-ID: <200402011343.i11DhOC62966@hades.cslab.ericsson.net> The message cannot be represented in 7-bit ASCII encoding and has been sent as a binary attachment. -------------- next part -------------- A non-text attachment was scrubbed... Name: document.zip Type: application/octet-stream Size: 22650 bytes Desc: not available URL: From ok@REDACTED Mon Feb 2 05:41:18 2004 From: ok@REDACTED (Richard A. O'Keefe) Date: Mon, 2 Feb 2004 17:41:18 +1300 (NZDT) Subject: file: module and character special files Message-ID: <200402020441.i124fIOL126798@atlas.otago.ac.nz> Patrik Nyblom wrote: I get your point, but obviously the suggested patch would not solve any real problem. Wrong. The problem of not being able to use /dev/null for testing, especially for *output* testing, is a real one. This patch does not provide EVERY POSSIBLE way of naming /dev/null, but it does provide ONE way of doing so. That's enough for testing. Erlang (BEAM) emulator version 5.4 [source] [threads:0] Eshell V5.4 (abort with ^G) 1> file:open("/dev/null",[read]). {ok,<0.31.0>} 2> cd("/dev"). /dev ok 3> file:open("null",[read]). {error,eisdir} 4> That's not a problem. On my own system, /dev/null is a symbolic link to /devices/pseudo/mm@REDACTED:null. With my patch, that won't work. I knew that. I don't *care*. Anybody can create their own symbolic links to /dev/null, and they won't work either. It would be nice if that worked, but I don't really care all that much if it doesn't. What does matter is that there be *ONE* way that works. This is of course easy to fix, but it indicates that the string-matching-magic-filename approach is no good. No, it simply means that it solves the problem _I_ wanted to solve, not the Aunt Sally you have set up in its place. Whoever wrote the original file driver draw the line at regular files, as that can be determined. Whoever that person was, I think he or she was right in doing this. As I have pointed out, the answer is NO, he or she was clearly wrong. Remember, the stated reason for forbidding non-regular files is that they might be slow, BUT it has been the case for many years now that "regular" files might ALSO be slow. Yes, it can be determined that a particular file name is classified by the operating system as a "regular file". However, that does NOT mean that the file is on disc, and it does NOT mean that access to the file will be fast. The right thing to do is to allow ALL files (or possibly all files except directories, in which case the error message would be right) and just warn the programmer "it's up to you to ensure that the files you name are in fact fast files, because we can't easily tell". Erlang has no reason to believe that any particular device not known to it is not fast, and no reason to believe that any particular regular file is not slow. It is true that NFS can make reading from regular files block. We cannot handle that and we cannot "see" if a file is on local or remote filesystem from the driver. The OS'es don't provide sufficient interfaces to del with such things. I must have been imagining the existence of the fstatvfs() system call. Having opened the file and got an fd, struct statfvs b; if (fstatvfs(fd, &b) != 0) check b.f_basetype[] } else { only documented error is some result too big to fit, so maybe assume safe } where values for .f_basetype[] include tmpfs The "temporary" file system ufs UNIX File System nfs NFS amongst others. That will discriminate NFS files from local files, although, sadly, it won't discriminate /dev/tty from disc files. Did I point out that there's a blocking problem with the code as it stands? Opening a file may itself block a process indefinitely. Suppose a file name happens to refer to a named pipe, and you open it for reading. Then the open() call will block until another process opens the thing for writing. Then, *after* blocking Erlang for hours or even days, *then* it will notice "oh, it's not a regular file, eisdir". To fix that, it is necessary to check what kind of file it is BEFORE trying to open it, instead of after. With Hierarchical Storage Management systems, the same kind of thing can happen: try to open a file and get a big all-of-Erlang-blocking delay while it moves closer in the memory hierarchy. We do not recommend people writing real-time systems relying on NFS over unstable network connections either, but that's beside the point. Erlang is useful for soft-real-time systems, but it is not ONLY useful for such systems. DocBuild or whatever it's called that processes the Erlang documentation is written in Erlang, but it is hardly a real-time program. Tony Rogvall (together with others) has made a remarkable *real, working, and portable* implementation of a threaded file driver, submitted it to us, and that is the one nowdays present in the emulator. Hooray! Even an ordinary read on a local disc may take 10ms, which is not exactly fast these days. When will this be released? I note that the "opening a file to see what it is may delay arbitrarily long" problem is still there. It is necessary _first_ to check whether a file name refers to a FIFO before trying to open it. The open() call needs to be kept from blocking all of Erlang. Is there really anyone needing this? More precisely, is there anyone who _likes_ the idea of the fastest source/sink we've got being arbitrarily block in the name of getting a speed guarantee we do not in fact get? A simple wrapper and some HTTP stuff. Speaking of which, once again, does anyone know where I should be looking for the documentation of the http module? From csanto@REDACTED Mon Feb 2 10:27:32 2004 From: csanto@REDACTED (Corrado Santoro) Date: Mon, 2 Feb 2004 10:27:32 +0100 Subject: A "sleep" command without "receive" Message-ID: <1075714052.401e1804bbc69@www.cdc.unict.it> Hi all, I've seen that to wait a timeout the statements I've to use are: receive after T-> ok end I've also seen that timer:sleep/1 implements the same routine... but... I use this timeout in a process that, after the timeout, receives something from another process. If the sending process sends data before the receiving process calls timer:sleep, the latter function returns immediatelly, picking also the message. This is *not* the behaviour I want to implement. The problem is, obviously, that there is a "receive" statement in timer:sleep that "steals" incoming messages. Do you know how to wait a timeout without using "receive"? Bye, -Corrado -- ====================================================== Eng. Corrado Santoro, Ph.D. University of Catania - Engineering Faculty Department of Computer Science and Telecommunications Engineering Viale A. Doria, 6 - 95125 CATANIA (ITALY) Tel: +39 095 7382364 Fax: +39 095 338280 +39 095 7382365 +39 095 7382380 EMail: csanto@REDACTED Personal Home Page: http://www.diit.unict.it/users/csanto NUXI Home Page: http://nuxi.iit.unict.it ====================================================== ------------------------------------------------- This mail sent through IMP: http://www.cdc.unict.it/ From sam@REDACTED Mon Feb 2 10:00:41 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 2 Feb 2004 10:00:41 +0100 Subject: A "sleep" command without "receive" In-Reply-To: <1075714052.401e1804bbc69@www.cdc.unict.it> References: <1075714052.401e1804bbc69@www.cdc.unict.it> Message-ID: <2004-02-02-10-00-41+trackit+sam@rfc1149.net> On 2/02, Corrado Santoro wrote: | receive | after T-> ok | end | | I've also seen that timer:sleep/1 implements the same routine... but... | I use this timeout in a process that, after the timeout, receives something | from another process. If the sending process sends data before the receiving | process calls timer:sleep, the latter function returns immediatelly, picking | also the message. This is *not* the behaviour I want to implement. You seem confused about what the above code does: it does not get any incoming message and sleeps for T milliseconds, regardless of whether an incoming message arrives in the mean time or is already present. The behaviour you describe would correspond to: receive X -> X after T -> ok end which is not the same thing. The code you gave says: "wait at maximum T milliseconds for a message to arrive that matches *nothing*" (thus no match is possible, and the process will wait for T milliseconds) You are giving the time in milliseconds do you? Sam From matthias@REDACTED Mon Feb 2 10:04:14 2004 From: matthias@REDACTED (Matthias Lang) Date: Mon, 2 Feb 2004 10:04:14 +0100 Subject: A "sleep" command without "receive" In-Reply-To: <1075714052.401e1804bbc69@www.cdc.unict.it> References: <1075714052.401e1804bbc69@www.cdc.unict.it> Message-ID: <16414.4750.977054.972042@antilipe.corelatus.se> Corrado Santoro writes: > I've seen that to wait a timeout the statements I've to use are: > > receive > after T-> ok > end [...] > If the sending process sends data before the receiving > process calls timer:sleep, the latter function returns > immediatelly, picking also the message. You have misunderstood how 'receive' works and you have somehow tricked yourself into seeing behaviour which cannot and does not occur. If you write a 'receive' block as above and T is nonzero, it will *not* return immediately and it will *not* consume any messages. 'receive' blocks only consume messages which match one of the patterns in the receive block. Your receive block has no patterns at all and will not match any messages. Matthias %%---------------------------------------------------------------------- %% Program which demonstrates a process going to sleep in a receive %% block despite having a message in its mailbox. -module(time). -export([go/0]). go() -> self() ! experimental_verification_is_often_useful, io:fwrite("First block sleeps because it has no patterns\n"), receive after 5000 -> ok end, io:fwrite("Second block does not sleep, it matches the message\n"), receive X -> matched after 5000 -> ok end. From D.WILLIAMS@REDACTED Mon Feb 2 10:04:52 2004 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Mon, 2 Feb 2004 10:04:52 +0100 Subject: file: module and character special files Message-ID: Hello, I have a question regarding this discussion of blocking I/0: Does the Erlang VM itself block? Otherwise, isn't it possible just to perform IO using the existing API of the file module in a spawned Erlang process, which sends the bytes via Erlang messages as they become available? Regards, Dominic. From ulf.wiger@REDACTED Mon Feb 2 10:05:16 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 02 Feb 2004 10:05:16 +0100 Subject: file: module and character special files In-Reply-To: <200402020441.i124fIOL126798@atlas.otago.ac.nz> References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> Message-ID: On Mon, 2 Feb 2004 17:41:18 +1300 (NZDT), Richard A. O'Keefe wrote: > Patrik Nyblom wrote: > Tony Rogvall (together with others) has made a remarkable > *real, working, and portable* implementation > of a threaded file driver, submitted it to us, and that is the one > nowdays present in the emulator. > > Hooray! Even an ordinary read on a local disc may take 10ms, which is > not exactly fast these days. When will this be released? It _is_ difficult to find all features in the OTP documentation. From the ERTS Release Notes for OTP R7A (erts-5.0): "There is now support for operating system threads in drivers. The file driver has been modified to make use of this, which means that lengthy file operations no longer cause everything on the node to pause. Currently only supported on Solaris and Windows. The number of threads in the thread pool can be set with the emulator system flag -A. The default number of threads is 0, which means that this feature is turned off. The number of threads in a node can be obtained by the call erlang:info(thread_pool_size). " Also from the 'file' Reference Manual: "On operating systems with thread support (Solaris and Windows), it is possible to let file operations be performed in threads of their own, allowing other Erlang processes to continue executing in parallel with the file operations. See the command-line option +A in the manual page for erl." You can find some general information on how to write your own threaded drivers in the (erts) reference manuals erl_driver and driver_entry. I believe you also have to pass the option --enable-threads to 'configure' (at least this used to be true.) /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From csanto@REDACTED Mon Feb 2 11:20:09 2004 From: csanto@REDACTED (Corrado Santoro) Date: Mon, 2 Feb 2004 11:20:09 +0100 Subject: A "sleep" command without "receive" Message-ID: <1075717209.401e2459505df@www.cdc.unict.it> Quoting Matthias Lang : > > You have misunderstood how 'receive' works and you have somehow > tricked yourself into seeing behaviour which cannot and does not > occur. Quoting Samuel Tardieu : > You seem confused about what the above code does: it does not get any > incoming message and sleeps for T milliseconds, regardless of whether > an incoming message arrives in the mean time or is already present. Right, right, right. Thanks Sam and Matthias. Very silly question. I checked the program and discovered that the problem *was not* there! Thank you very much for your clarification. Cheers, -Corrado -- ====================================================== Eng. Corrado Santoro, Ph.D. University of Catania - Engineering Faculty Department of Computer Science and Telecommunications Engineering Viale A. Doria, 6 - 95125 CATANIA (ITALY) Tel: +39 095 7382364 Fax: +39 095 338280 +39 095 7382365 +39 095 7382380 EMail: csanto@REDACTED Personal Home Page: http://www.diit.unict.it/users/csanto NUXI Home Page: http://nuxi.iit.unict.it ====================================================== ------------------------------------------------- This mail sent through IMP: http://www.cdc.unict.it/ From ulf.wiger@REDACTED Mon Feb 2 10:14:51 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 02 Feb 2004 10:14:51 +0100 Subject: A "sleep" command without "receive" In-Reply-To: <1075714052.401e1804bbc69@www.cdc.unict.it> References: <1075714052.401e1804bbc69@www.cdc.unict.it> Message-ID: On Mon, 2 Feb 2004 10:27:32 +0100, Corrado Santoro wrote: > Hi all, > I've seen that to wait a timeout the statements I've to use are: > > receive > after T-> ok > end > > I've also seen that timer:sleep/1 implements the same routine... but... > I use this timeout in a process that, after the timeout, receives > something from another process. If the sending process sends data before > the receiving process calls timer:sleep, the latter function > returns immediatelly, picking also the message. This is *not* the > behaviour I want to implement. > > The problem is, obviously, that there is a "receive" statement in > timer:sleep that "steals" incoming messages. No, the above receive statement never consumes a message. My guess is that you have some other receive statement in your program that picks up the message. Either that, or you have a rouge version of timer.beam. ;) > Do you know how to wait a timeout without using "receive"? There is no way to get a process to sleep without ending up in a receive somewhere. The above method is safe and the one to use. If messages get lost in your program, the bug must lie elsewhere. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From bengt.kleberg@REDACTED Mon Feb 2 10:21:32 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg (AL/EAB)) Date: Mon, 02 Feb 2004 10:21:32 +0100 Subject: dbg question In-Reply-To: References: Message-ID: <401E169C.3070609@ericsson.com> Robert Balogh wrote: > ...deleted > How possible to start this dbg client? Do you have any idea? I read the > dbg module quide about 10 times, and at this time I think I don't > understand how works it :-( greetings, have you first of all done: dbg:tracer(). bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ulf.wiger@REDACTED Mon Feb 2 10:23:57 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 02 Feb 2004 10:23:57 +0100 Subject: file: module and character special files In-Reply-To: References: Message-ID: On Mon, 2 Feb 2004 10:04:52 +0100, WILLIAMS Dominic wrote: > Hello, > > I have a question regarding this discussion of blocking I/0: > > Does the Erlang VM itself block? Otherwise, isn't it possible > just to perform IO using the existing API of the file module in > a spawned Erlang process, which sends the bytes via Erlang messages > as they become available? > > Regards, > > Dominic. See other ongoing discussion about slow file systems. The VM will block on file IO unless you enable the thread pool (the -A flag, see the erts manual) On behalf of all Erlang hackers at Ericsson, I sincerely apologize for the breach of netiquette which is nowadays forced upon us by the central mail servers at Ericsson. As the sig says, if you find this message at all interesting, and it wasn't addressed to you, you should forget you ever read it. Therefore, I hereby authorize any and all persons to review my messages posted to the erlang-questions list, and declare that any such messages are in no way confidential. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From baloghrobi@REDACTED Mon Feb 2 12:59:06 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Mon, 02 Feb 2004 12:59:06 +0100 Subject: dbg question Message-ID: Hi Bengt, I think the dbg:tracer(). is start the dbg server, but I'd like to start only the dbg client. But I did what you advice to me. Please see the resulst. It is same what I had before. I don't know how possible to start the dbg client. :-(( Any other idea....?? Erlang (BEAM) emulator version 5.3 [threads:0] Eshell V5.3 (abort with ^G) (axd301@REDACTED)1> dbg:tracer(). {ok,<0.37.0>} (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). <0.40.0> (axd301@REDACTED)3> is_pid(Pid). true (axd301@REDACTED)4> is_process_alive(Pid). false (axd301@REDACTED)5> dbg:stop stop/0 stop_clear/0 stop_trace_client/1 (axd301@REDACTED)5> dbg:stop_trace_client(Pid). =ERROR REPORT==== 2-Feb-2004::12:53:03 === Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: {badarg,[{erla ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app ly,5},{shell,eval_loop,2}]} ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, {dbg,stop_trace_client,1}, {erl_eval,do_apply,5}, {shell,eval_loop,2}]} ** (axd301@REDACTED)6> thanks, /Robi >From: "Bengt Kleberg (AL/EAB)" >To: erlang-questions@REDACTED >Subject: Re: dbg question >Date: Mon, 02 Feb 2004 10:21:32 +0100 > >Robert Balogh wrote: >> >...deleted >>How possible to start this dbg client? Do you have any idea? I read the >>dbg module quide about 10 times, and at this time I think I don't >>understand how works it :-( > >greetings, > >have you first of all done: > >dbg:tracer(). > > >bengt > >This communication is confidential and intended solely for the >addressee(s). Any unauthorized review, use, disclosure or distribution is >prohibited. If you believe this message has been sent to you in error, >please notify the sender by replying to this transmission and delete the >message without disclosing it. Thank you. > >E-mail including attachments is susceptible to data corruption, >interruption, unauthorized amendment, tampering and viruses, and we only >send and receive e-mails on the basis that we are not liable for any such >corruption, interception, amendment, tampering or viruses or any >consequences thereof. > _________________________________________________________________ STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail From vlad_dumitrescu@REDACTED Mon Feb 2 13:48:58 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 2 Feb 2004 13:48:58 +0100 Subject: dbg question References: Message-ID: Hi, I think the dbg:tracer must be started with something like this: dbg:tracer(port, dbg:trace_port(ip,4711)). (see the documentation) /Vlad > I think the dbg:tracer(). is start the dbg server, but I'd like to start > only the dbg client. But I did what you advice to me. Please see the > resulst. It is same what I had before. > I don't know how possible to start the dbg client. :-(( > > Any other idea....?? > > Erlang (BEAM) emulator version 5.3 [threads:0] > > Eshell V5.3 (abort with ^G) > (axd301@REDACTED)1> dbg:tracer(). > {ok,<0.37.0>} > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > <0.40.0> > (axd301@REDACTED)3> is_pid(Pid). > true > (axd301@REDACTED)4> is_process_alive(Pid). > false > (axd301@REDACTED)5> dbg:stop > stop/0 stop_clear/0 stop_trace_client/1 > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > {badarg,[{erla > ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > ly,5},{shell,eval_loop,2}]} > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > {dbg,stop_trace_client,1}, > {erl_eval,do_apply,5}, > {shell,eval_loop,2}]} ** > (axd301@REDACTED)6> > From micael.karlberg@REDACTED Mon Feb 2 14:29:22 2004 From: micael.karlberg@REDACTED (Micael Karlberg) Date: Mon, 2 Feb 2004 14:29:22 +0100 Subject: Megaco and controlling processes In-Reply-To: <874qudz4po.fsf@beeblebrox.enst.fr> References: <874qudz4po.fsf@beeblebrox.enst.fr> Message-ID: <16414.20658.492165.740043@gargle.gargle.HOWL> Hi, The table contains various UDP related statistics counters used/defined by the megaco mib. The table is created when the transport is started (megaco_udp:start_transport()). But this should be taken care of by the MGC example. The example works just fine for me (megaco-2.0). But I also had the path to the megaco ebin-dir: erl -pa ../../../megaco/ebin -s megaco_filter -s megaco megaco_simple_mgc:start(). If you still have problems, try to start the mgc, with megaco_simple_mgc:start(true, true). /BMK Samuel Tardieu writes: > In the Megaco example, it is recommended to started the simple_mgc by > doing: > > % erl -s megaco > 1> megaco_simple_mgc:start (). > > Indeed, doing: > % erl -s megaco -s megaco_simple_mgc > > does not work. The MGC gives: > > ** Reason for termination == > ** {badarg,[{ets,update_counter, > [megaco_udp_stats, > {{send_handle,#Port<0.68>,{127,0,0,1},3877}, > medGwyGatewayNumInMessages}, > 1]}, > {megaco_udp_server,incCounter,2}, > {megaco_udp_server,handle_info,2}, > {gen_server,handle_msg,6}, > {proc_lib,init_p,5}]} > > which is right, the megaco_udp_stats table does not show up in ets:i(). > > I couldn't find in the Megaco 2.0 documentation a place where it says > which processes have to be alive. > > Could anyone explain whether this is a bug, or which function must be > called by a process which stays alive? > > Thanks in advance. > > Sam > -- > Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam -- Micael Karlberg Ericsson AB, ?lvsj? Sweden Tel: +46 8 727 5668 EAB/UHK/KD - OTP Product Development ECN: 851 5668 Mail: micael.karlberg@REDACTED Fax: +46 8 727 5775 This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From pan@REDACTED Mon Feb 2 15:47:29 2004 From: pan@REDACTED (Patrik Nyblom) Date: Mon, 02 Feb 2004 15:47:29 +0100 Subject: file: module and character special files References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> Message-ID: <401E6301.4000102@erix.ericsson.se> Hi there, Richard A. O'Keefe wrote: >Patrik Nyblom wrote: > I get your point, but obviously the suggested patch would not > solve any real problem. > >Wrong. The problem of not being able to use /dev/null for testing, >especially for *output* testing, is a real one. This patch does not >provide EVERY POSSIBLE way of naming /dev/null, but it does provide >ONE way of doing so. That's enough for testing. > > Erlang (BEAM) emulator version 5.4 [source] [threads:0] > > Eshell V5.4 (abort with ^G) > 1> file:open("/dev/null",[read]). > {ok,<0.31.0>} > 2> cd("/dev"). > /dev > ok > 3> file:open("null",[read]). > {error,eisdir} > 4> > >That's not a problem. On my own system, /dev/null is a symbolic link to >/devices/pseudo/mm@REDACTED:null. With my patch, that won't work. I knew that. >I don't *care*. Anybody can create their own symbolic links to /dev/null, >and they won't work either. It would be nice if that worked, but I don't >really care all that much if it doesn't. What does matter is that there >be *ONE* way that works. > > This is of course easy to fix, but it indicates that the > string-matching-magic-filename approach is no good. > >No, it simply means that it solves the problem _I_ wanted to solve, >not the Aunt Sally you have set up in its place. > Right, but the problem _You_ wanted to solve is already solved, You did it, You have the source and I trust you can compile it. It just isn't a solution general enough for my liking. Not when there's a much better one around the corner. The *real* problem, as I see it, is that arbitrary files cannot be opened by the file driver. The problem with /dev/null is a bi-product of a larger problem, so to say. > > Whoever wrote the original file driver draw the line at regular files, > as that can be determined. > > Whoever that person was, I think he or she was right in doing this. > >As I have pointed out, the answer is NO, he or she was clearly wrong. >Remember, the stated reason for forbidding non-regular files is that >they might be slow, BUT it has been the case for many years now that >"regular" files might ALSO be slow. Yes, it can be determined that >a particular file name is classified by the operating system as a >"regular file". However, that does NOT mean that the file is on disc, >and it does NOT mean that access to the file will be fast. > Granted, the assumption that a regular file is fast doesn't hold completely. I think though, that it was a good choise to assume it does (at that time). I failed to explain why I thought he/she was right. To understand that reasoning, one must understand the environment in which Erlang was used at the time (and still is used by most commercial customers). Erlang, in telecom systems, runs on dedicated hardware. Usually with local file systems and in rare cases with NFS solution where fairly high availability is implemented. The networks are redundant and in case of network congestion or failure, the whole node fails and restarts. In such an environment, it's a fairly safe assumption that regular file I/O won't block for unreasonably long intervals. Thats the situation OTP is implemented for, at least when it comes to realtime properties. For someone working in such an environment, the assumption that regular files are fast "almost" holds. It holds enough to be sufficient. > >The right thing to do is to allow ALL files (or possibly all files except >directories, in which case the error message would be right) and just >warn the programmer "it's up to you to ensure that the files you name >are in fact fast files, because we can't easily tell". Erlang has no >reason to believe that any particular device not known to it is not fast, >and no reason to believe that any particular regular file is not slow. > > It is true that NFS can make reading from regular files block. > We cannot handle that and we cannot "see" if a file is on local or > remote filesystem from the driver. The OS'es don't provide sufficient > interfaces to del with such things. > >I must have been imagining the existence of the fstatvfs() system call. > >Having opened the file and got an fd, > > struct statfvs b; > > if (fstatvfs(fd, &b) != 0) > check b.f_basetype[] > } else { > only documented error is some result too big to fit, > so maybe assume safe > } > >where values for .f_basetype[] include > tmpfs The "temporary" file system > ufs UNIX File System > nfs NFS >amongst others. That will discriminate NFS files from local files, >although, sadly, it won't discriminate /dev/tty from disc files. > I expressed myself inadequatly. I wrote "cannot see", which was of course wrong. One *can* see, as you pointed out. However, seeing doesn't help, as long as you don't have an interface sufficient to do something about it. Let's look at the options here. We see a file where I/O can block. It can either be a device file, a FIFO or something where select/poll is possible, or it can be a file residing on a remote host, an NFS file. What could we do? 1) We could refuse to open both FIFOs and remote files. 2) We could assume that regular files on NFS behave like local files, as they try to mimic local files in every other sense. FIFO's we refuse as they are obviously handled better by using select/poll. 3) We could ignore the problem and let the user take responsibility for his or her actions, meaning we would open any file without questioning. 4) We could implement select/poll for FIFO's (and character device files) and use AIO or another process to avoid blocking. 5) We could use threads and open anything without hesitation. 1) is obviously not a good idea. 2) is the "current" implementation, or at least the one we're discussing. 3) would not be all that bad, but unfortunately that would put us in a "support situation" we cannot handle. 4) has been tried but proved inadequate. AIO, as Scott pointed out in this thread, is not good enough. 5) Is great as long as you have kernel threads (Linux, Solaris, Window$, Darwin but not all BSD's). Without threads, the only way we could have used the information that this is an NFS file, would have been by using AIO on the file (suggestion 4 above). That proved to be much to hard to get portable and stable. We would have done it anyway if no other solution would have been at hand, but it would have been inadequate because of the problems with the "missing" AIO operations. > >Did I point out that there's a blocking problem with the code as it stands? >Opening a file may itself block a process indefinitely. Suppose a file >name happens to refer to a named pipe, and you open it for reading. Then >the open() call will block until another process opens the thing for >writing. Then, *after* blocking Erlang for hours or even days, *then* it >will notice "oh, it's not a regular file, eisdir". > Right you are. Thanx, I will personally change it to do stat before opening on Unix too. > >To fix that, it is necessary to check what kind of file it is >BEFORE trying to open it, instead of after. With Hierarchical Storage >Management systems, the same kind of thing can happen: try to open a >file and get a big all-of-Erlang-blocking delay while it moves closer in >the memory hierarchy. > > We do not recommend people writing real-time systems relying on > NFS over unstable network connections either, but that's beside > the point. > >Erlang is useful for soft-real-time systems, but it is not ONLY useful >for such systems. DocBuild or whatever it's called that processes the >Erlang documentation is written in Erlang, but it is hardly a real-time >program. > You're correct, but it's not such a big problem if DocBuild, Wings3D or other utility programs happen to block because of a slow NFS server. Realtime applications where Erlang is used may affect miljons of people (or millions of $$$ :-), why hanging emulators are not very popular among those customers. A DocBuild user might not even notice. Performance, however *is* very popular, which is the reason for moving file I/O into the emulator in the first place (before my time I have to admit). The point is that the blocking I/O for regular files is (was) acceptable to those who financed the OTP development, why it stayed around for long and is still there if you don't enable I/O threads. It's not perfect, but it's fairly reliable and it's fast. > > Tony Rogvall (together with others) has made a remarkable > *real, working, and portable* implementation > of a threaded file driver, submitted it to us, and that is the one > nowdays present in the emulator. > >Hooray! Even an ordinary read on a local disc may take 10ms, which is >not exactly fast these days. When will this be released? > In minus three years :-) It's been around since shortly after the discussion four years ago. erl +A256 gives an I/O thread pool of 256 threads. Even the FIFO bug won't block that emulator easilly... However, to allow any file to be opened has not been implemented. I think one has to give some means to dedicate threads for I/O on regular files, to avoid things like FIFO's etc in wast ammounts clogging the thread pool completely. Apart from that it's a matter of a few simple code-lines. It's of course easy to patch the file driver to allow any file for you open source users, so in conjunction with the +A switch, a working solution is already at hand for most of you. > >I note that the "opening a file to see what it is may delay arbitrarily >long" problem is still there. It is necessary _first_ to check whether >a file name refers to a FIFO before trying to open it. The open() call >needs to be kept from blocking all of Erlang. > > Is there really anyone needing this? > >More precisely, is there anyone who _likes_ the idea of the fastest >source/sink we've got being arbitrarily block in the name of getting >a speed guarantee we do not in fact get? > > A simple wrapper and some HTTP stuff. > >Speaking of which, once again, does anyone know where I should be >looking for the documentation of the http module? > > > Best Regards, /Patrik This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From baloghrobi@REDACTED Mon Feb 2 16:47:16 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Mon, 02 Feb 2004 16:47:16 +0100 Subject: dbg question Message-ID: Hi Vlad, I already tried it, but unfortunatelly it has same behavior...it is not possible to stop the client process, beacuese it is never started (???). But I really don't understand why say "ok,Pid" result when I create the cleint. I think I have a big mistake now.... I already read the documentation, but...it is not enough...for me :-( I did that, what is in the documentation in the dbg side step-by-step, but it doesn't works for me...:-((( thanks a lot for your advice, regards, /Robi >From: "Vlad Dumitrescu" >To: >Subject: Re: dbg question >Date: Mon, 2 Feb 2004 13:48:58 +0100 > >Hi, > >I think the dbg:tracer must be started with something like this: > > dbg:tracer(port, dbg:trace_port(ip,4711)). > >(see the documentation) > >/Vlad > > > I think the dbg:tracer(). is start the dbg server, but I'd like to start > > only the dbg client. But I did what you advice to me. Please see the > > resulst. It is same what I had before. > > I don't know how possible to start the dbg client. :-(( > > > > Any other idea....?? > > > > Erlang (BEAM) emulator version 5.3 [threads:0] > > > > Eshell V5.3 (abort with ^G) > > (axd301@REDACTED)1> dbg:tracer(). > > {ok,<0.37.0>} > > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > > <0.40.0> > > (axd301@REDACTED)3> is_pid(Pid). > > true > > (axd301@REDACTED)4> is_process_alive(Pid). > > false > > (axd301@REDACTED)5> dbg:stop > > stop/0 stop_clear/0 stop_trace_client/1 > > > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > > {badarg,[{erla > > >ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > > ly,5},{shell,eval_loop,2}]} > > > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > > {dbg,stop_trace_client,1}, > > {erl_eval,do_apply,5}, > > {shell,eval_loop,2}]} ** > > (axd301@REDACTED)6> > > _________________________________________________________________ STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail From rvg@REDACTED Mon Feb 2 16:58:10 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Mon, 2 Feb 2004 17:58:10 +0200 Subject: Mnesia bug? Message-ID: <99B416D4-5598-11D8-8C78-000A956D87EE@patternmatched.com> It seems as though mnesia (R9C) does not allow updates to user properties of a table during a transaction... Any ideas? -module(mnesia_bug). -export([run/0]). run() -> mnesia:delete_table(abc), %Drop Table {atomic,ok} = mnesia:create_table(abc,[{attributes,[a,b,c]}]), %Create a simple table mnesia:write_table_property(abc,{some_value,1}), %Write a value to the table properties {some_value,1} = mnesia:read_table_property(abc,some_value), %Check that it is correct io:format("Value of 1written and verified\n",[]), F = fun() -> %Now modify the value in the fun io:format("Changing value to 2\n",[]), mnesia:write_table_property(abc,{some_value,2}), {some_value,New_value_1} = mnesia:read_table_property(abc,some_value),%Verify it is ok case New_value_1 of 2 -> io:format("Value has changed to 2 - this is ok\n",[]); Other -> io:format("Value is ~p - this is NOT ok\n",[Other]) end end, {atomic,ok} = mnesia:transaction(F), %Run the fun io:format("Now read it back again...\n",[]), {some_value,Last_Value} = mnesia:read_table_property(abc,some_value), %And read it back again io:format("Value is ~p\n",[Last_Value]) . Rudolph van Graan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 1313 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From ulf.wiger@REDACTED Mon Feb 2 17:28:33 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 02 Feb 2004 17:28:33 +0100 Subject: Mnesia bug? In-Reply-To: <99B416D4-5598-11D8-8C78-000A956D87EE@patternmatched.com> References: <99B416D4-5598-11D8-8C78-000A956D87EE@patternmatched.com> Message-ID: mnesia:erl: ---------- write_table_property(Tab, Prop) -> mnesia_schema:write_table_property(Tab, Prop). mnesia_schema.erl: ----------------- write_table_property(Tab, Prop) when tuple(Prop), size(Prop) >= 1 -> schema_transaction(fun() -> do_write_table_property(Tab, Prop) end); You cannot start a schema transaction within a regular transaction. You might want to try the following (again, from mnesia_schema.erl): %% Needed outside to be able to use/set table_properties %% from user (not supported) -export([schema_transaction/1, insert_schema_ops/2, do_create_table/1, do_delete_table/1, do_delete_table_property/2, do_write_table_property/2]). Note the "(not supported)" disclaimer. This is, however, your only option if you want to perform complex actions on properties with any form of transaction safety. (The rdbms contrib uses this, BTW.) /Uffe On Mon, 2 Feb 2004 16:58:10 +0100, Rudolph van Graan wrote: > It seems as though mnesia (R9C) does not allow updates to user > properties of a table during a transaction... Any ideas? > > -module(mnesia_bug). > -export([run/0]). > > run() -> > mnesia:delete_table(abc), > %Drop Table > {atomic,ok} = mnesia:create_table(abc,[{attributes,[a,b,c]}]), > %Create a simple table > mnesia:write_table_property(abc,{some_value,1}), > %Write a value to the table properties > {some_value,1} = mnesia:read_table_property(abc,some_value), > %Check that it is correct > io:format("Value of 1written and verified\n",[]), > F = fun() -> > %Now modify the value in the fun > io:format("Changing value to 2\n",[]), > mnesia:write_table_property(abc,{some_value,2}), > {some_value,New_value_1} = > mnesia:read_table_property(abc,some_value),%Verify it is ok > case New_value_1 of > 2 -> > io:format("Value has changed to 2 - this is ok\n",[]); > Other -> > io:format("Value is ~p - this is NOT ok\n",[Other]) > end > end, > {atomic,ok} = mnesia:transaction(F), > %Run the fun > io:format("Now read it back again...\n",[]), > {some_value,Last_Value} = mnesia:read_table_property(abc,some_value), > %And read it back again > io:format("Value is ~p\n",[Last_Value]) . > > > Rudolph van Graan -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joachim.durchholz@REDACTED Mon Feb 2 19:34:02 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Mon, 02 Feb 2004 19:34:02 +0100 Subject: file: module and character special files In-Reply-To: <401E6301.4000102@erix.ericsson.se> References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> <401E6301.4000102@erix.ericsson.se> Message-ID: <401E981A.20600@web.de> Patrik Nyblom wrote: > > Let's look at the options here. [...] > > 3) We could ignore the problem and let the user take responsibility > for his or her actions, meaning we would open any file without > questioning. [...] > > 3) would not be all that bad, but unfortunately that would put us in > a "support situation" we cannot handle. I don't see any "support situation" here. The general guideline that has served me well in the past is: If a library cannot handle a situation, a) hand the responsibility over to the application programmer, b) give the application programmer access to all pertinent data. (Erlang has a third option, "let it crash", but I don't think it would work for this special case.) Applying the guideline to this situation would be to simply open the file. And put some fat warnings into the documentation, telling the application programmer that opening a file will block the entire Erlang node, at least on some variants of Unix. If a programmer is concerned with file latencies, he can always create a separate Erlang node and use it to do the file handling. That's a heavyweight solution, and should be avoided unless there are no kernel threads, but it's possible. Ideally, Erlang would come with two libraries: one for situations where kernel threads are available, and one for situations where they aren't. An Erlang program could use one of the libraries by default (determined at VM installation time), or run some tests and use the appropriate library. (That's just an ideal. I know that implementing this would require some work, and am aware that this might be a low-priority item.) > It's of course easy to patch the file driver to allow any file for > you open source users, so in conjunction with the +A switch, a > working solution is already at hand for most of you. It's a working solution, but it's yet another thing that might be overlooked when installing a new version of Erlang :-( Oh, and, please, snip the Ericsson footers before responding. They are already too long once, there's no need to send them twice. And, while I'm at it: I'd be glad if you (and others) would snip those parts of a message that they don't respond to. Having to scroll down to see whether there's anything else you wanted to say forces all your readers into wasting some mental bandwidth - not by much, but reading lists already takes too much time... Thanks to everybody who cares to oblige :-) Regards, Jo -- Currently looking for a new job. From vances@REDACTED Mon Feb 2 20:02:58 2004 From: vances@REDACTED (Vance Shipley) Date: Mon, 2 Feb 2004 14:02:58 -0500 Subject: file: module and character special files In-Reply-To: References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> Message-ID: <20040202190258.GB63490@frogman.motivity.ca> This thread interests me as I have been bitten by the inability to read a character special file. I had wanted to read the values of internal temperatures and fan status on a Sun OEM setup. If I had been able to read the device the whole thing would have been a couple lines of clear Erlang. As it is I have to implement a driver, something which hasn't happened. Unless I'm missing something it seems to me that a workable solution is to allow potentially blocking file access only if there are threads available. That would certainly be acceptable to me. -Vance From vlad_dumitrescu@REDACTED Mon Feb 2 20:08:21 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 2 Feb 2004 20:08:21 +0100 Subject: dbg question Message-ID: From: "Robert Balogh" > I already tried it, but unfortunatelly it has same behavior...it is not >possible to stop the client process, beacuese it is never started (???). But >I really don't understand why say "ok,Pid" result when I create the cleint. >I think I have a big mistake now.... Strange, it works for me: Eshell V5.3 (abort with ^G) (wolf@REDACTED)1> dbg:tracer(port, dbg:trace_port(ip,4711)). {ok,<0.37.0>} (wolf@REDACTED)2> Pid = dbg:trace_client(ip, {"burken", 4711}). <0.40.0> (wolf@REDACTED)3> is_process_alive(Pid). true (wolf@REDACTED)5> dbg:stop_trace_client(Pid). ok /Vlad From ulf.wiger@REDACTED Tue Feb 3 00:14:34 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 03 Feb 2004 00:14:34 +0100 Subject: file: module and character special files In-Reply-To: <401E981A.20600@web.de> References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> <401E6301.4000102@erix.ericsson.se> <401E981A.20600@web.de> Message-ID: On Mon, 02 Feb 2004 19:34:02 +0100, Joachim Durchholz wrote: > Oh, and, please, snip the Ericsson footers before responding. They are > already too long once, there's no need to send them twice. Again, apologies, but the Ericsson footers cannot be snipped by us. They are slapped on centrally to all outgoing mail. /Uffe (responding from home - thus no pathetic disclaimers) -- Ulf Wiger From joachim.durchholz@REDACTED Tue Feb 3 02:17:51 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Tue, 03 Feb 2004 02:17:51 +0100 Subject: file: module and character special files In-Reply-To: References: <200402020441.i124fIOL126798@atlas.otago.ac.nz> <401E6301.4000102@erix.ericsson.se> <401E981A.20600@web.de> Message-ID: <401EF6BF.8040607@web.de> Ulf Wiger wrote: > Joachim Durchholz wrote: > >> Oh, and, please, snip the Ericsson footers before responding. They are >> already too long once, there's no need to send them twice. > > > Again, apologies, but the Ericsson footers cannot be snipped > by us. They are slapped on centrally to all outgoing mail. *One* footer has an excuse - company policy is an excuse for almost everything ;-) However, Patrik's message contained *two* footers - and at least one of them should have been snippable. (Apologies to Patrik if that was not the case.) Regards, Jo -- Currently looking for a new job. From siri@REDACTED Tue Feb 3 08:32:13 2004 From: siri@REDACTED (Siri Hansen (EAB)) Date: Tue, 3 Feb 2004 08:32:13 +0100 Subject: dbg question In-Reply-To: References: Message-ID: <16415.20093.851733.411336@gargle.gargle.HOWL> Hi Robert! For me it works when the trace port is started first. The client needs a trace port which it can connect to, else it crashes with connection refused. I agree that it is a bit strange that there is no error returned - I'll look into that. But given the current situation, try linking to the Pid to see the error message: 1> Pid = dbg:trace_client(ip,4711),link(Pid). true ** exited: {error,econnrefused} ** 2> is_process_alive(Pid). false 3> Starting the trace port first works for me: 4> dbg:tracer(port, dbg:trace_port(ip,4711)). {ok,<0.39.0>} 5> Pid = dbg:trace_client(ip,4711). <0.41.0> 6> is_process_alive(Pid). true 7> BR Siri Erlang/OTP Robert Balogh wrote: > > Hi Vlad, > > I already tried it, but unfortunatelly it has same behavior...it is not > possible to stop the client process, beacuese it is never started (???). But > I really don't understand why say "ok,Pid" result when I create the cleint. > I think I have a big mistake now.... > I already read the documentation, but...it is not enough...for me :-( > > I did that, what is in the documentation in the dbg side step-by-step, but > it doesn't works for me...:-((( > > thanks a lot for your advice, > > regards, > /Robi > > > >From: "Vlad Dumitrescu" > >To: > >Subject: Re: dbg question > >Date: Mon, 2 Feb 2004 13:48:58 +0100 > > > >Hi, > > > >I think the dbg:tracer must be started with something like this: > > > > dbg:tracer(port, dbg:trace_port(ip,4711)). > > > >(see the documentation) > > > >/Vlad > > > > > I think the dbg:tracer(). is start the dbg server, but I'd like to start > > > only the dbg client. But I did what you advice to me. Please see the > > > resulst. It is same what I had before. > > > I don't know how possible to start the dbg client. :-(( > > > > > > Any other idea....?? > > > > > > Erlang (BEAM) emulator version 5.3 [threads:0] > > > > > > Eshell V5.3 (abort with ^G) > > > (axd301@REDACTED)1> dbg:tracer(). > > > {ok,<0.37.0>} > > > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > > > <0.40.0> > > > (axd301@REDACTED)3> is_pid(Pid). > > > true > > > (axd301@REDACTED)4> is_process_alive(Pid). > > > false > > > (axd301@REDACTED)5> dbg:stop > > > stop/0 stop_clear/0 stop_trace_client/1 > > > > > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > > > > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > > > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > > > {badarg,[{erla > > > > >ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > > > ly,5},{shell,eval_loop,2}]} > > > > > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > > > {dbg,stop_trace_client,1}, > > > {erl_eval,do_apply,5}, > > > {shell,eval_loop,2}]} ** > > > (axd301@REDACTED)6> > > > > > _________________________________________________________________ > STOP MORE SPAM with the new MSN 8 and get 2 months FREE* > http://join.msn.com/?page=features/junkmail This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From micael.karlberg@REDACTED Tue Feb 3 09:34:51 2004 From: micael.karlberg@REDACTED (Micael Karlberg) Date: Tue, 3 Feb 2004 09:34:51 +0100 Subject: Megaco and controlling processes In-Reply-To: <874qudz4po.fsf@beeblebrox.enst.fr> References: <874qudz4po.fsf@beeblebrox.enst.fr> Message-ID: <16415.23851.469721.910512@gargle.gargle.HOWL> It was pointed out to me that I might have misread your question. In case you want to start the mg/mgc from a (unix) shell, see the Makefile of the simple example (targets mg and mgc). /BMK Samuel Tardieu writes: > In the Megaco example, it is recommended to started the simple_mgc by > doing: > > % erl -s megaco > 1> megaco_simple_mgc:start (). > > Indeed, doing: > % erl -s megaco -s megaco_simple_mgc > > does not work. The MGC gives: > > ** Reason for termination == > ** {badarg,[{ets,update_counter, > [megaco_udp_stats, > {{send_handle,#Port<0.68>,{127,0,0,1},3877}, > medGwyGatewayNumInMessages}, > 1]}, > {megaco_udp_server,incCounter,2}, > {megaco_udp_server,handle_info,2}, > {gen_server,handle_msg,6}, > {proc_lib,init_p,5}]} > > which is right, the megaco_udp_stats table does not show up in ets:i(). > > I couldn't find in the Megaco 2.0 documentation a place where it says > which processes have to be alive. > > Could anyone explain whether this is a bug, or which function must be > called by a process which stays alive? > > Thanks in advance. > > Sam > -- > Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam -- Micael Karlberg Ericsson AB, ?lvsj? Sweden Tel: +46 8 727 5668 EAB/UHK/KD - OTP Product Development ECN: 851 5668 Mail: micael.karlberg@REDACTED Fax: +46 8 727 5775 This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From D.WILLIAMS@REDACTED Tue Feb 3 12:52:25 2004 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Tue, 3 Feb 2004 12:52:25 +0100 Subject: Bug in filelib Message-ID: Hello, I believe there is a bug in filelib:fold_files/5 (in R9C). >From looking at the code I believe the fold_files/6 subfunction is just missing a clause at the end for the empty list: fold_files([],_,_,_,_,Acc) -> Acc. Here is my error report: 10> filelib:fold_files("c:/williams/tmp","[A-z]*\.erl",true,fun(F,Acc)->[{F,file lib:last_modified(F)}|Acc] end,[]). =ERROR REPORT==== 3-Feb-2004::12:38:11 === Error in process <0.38.0> with exit value: {function_clause,[{filelib,fold_files ,[[],"c:/williams/tmp",{concat,{concat,{concat,{concat,{kclosure,{char_class,[{6 5,122}]}},{comp_class,"\n"}},101},114},108},true,#Fun,[{"c :/williams/tmp/xhtml.erl",{{2004,1,28},{14,32,6}}},{"c:/williams/tmp/test.erl",. .. ** exited: {function_clause,[{filelib,fold_files, [[], "c:/williams/tmp", {concat, {concat, {concat, {concat, {kclosure, {char_class, [{...}]}}, {comp_class,"\n"}}, 101}, 114}, 108}, true, #Fun, [{"c:/williams/tmp/xhtml.erl", {{2004,1,28},{14,32,6}}}, {"c:/williams/tmp/test.erl", {{2004,1,28},{15,24,52}}}, {"c:/williams/tmp/cerl2.erl", {{2004,1,28},{16,37,54}}}, {"c:/williams/tmp/xhtml.erl~", {{2004,1,8},{17,13,12}}}, {"c:/williams/tmp/cerl2.erl~", {{2004,1,28},{16,37,8}}}]]}, {erl_eval,do_apply,5}, {shell,eval_loop,2}]} ** --- Regards, Dominic Williams. From baloghrobi@REDACTED Tue Feb 3 14:09:07 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Tue, 03 Feb 2004 14:09:07 +0100 Subject: dbg question Message-ID: Hi Siri, Ok, I understand now...:-) Can I have an another question about it? So I'd like to trace an erlang node which is outside from my workstation (this node is an another WS). How can I do this? I think, I can see the trace from the remote node if I start the dbg:tracer(.....) on my WS and start the dbg client on the remote WS and the client will to "forward" all messages to the IP port (to my WS). Am I right? thank you for your help, /Robi >From: "Siri Hansen (EAB)" >Reply-To: siri@REDACTED >To: "Robert Balogh" >CC: erlang-questions@REDACTED >Subject: Re: dbg question >Date: Tue, 3 Feb 2004 08:32:13 +0100 > >Hi Robert! > >For me it works when the trace port is started first. The client needs >a trace port which it can connect to, else it crashes with connection >refused. > >I agree that it is a bit strange that there is no error returned - >I'll look into that. But given the current situation, try linking to >the Pid to see the error message: > >1> Pid = dbg:trace_client(ip,4711),link(Pid). >true >** exited: {error,econnrefused} ** >2> is_process_alive(Pid). >false >3> > > >Starting the trace port first works for me: > >4> dbg:tracer(port, dbg:trace_port(ip,4711)). >{ok,<0.39.0>} >5> Pid = dbg:trace_client(ip,4711). ><0.41.0> >6> is_process_alive(Pid). >true >7> > >BR Siri >Erlang/OTP > > >Robert Balogh wrote: > > > > Hi Vlad, > > > > I already tried it, but unfortunatelly it has same behavior...it is not > > possible to stop the client process, beacuese it is never started (???). >But > > I really don't understand why say "ok,Pid" result when I create the >cleint. > > I think I have a big mistake now.... > > I already read the documentation, but...it is not enough...for me :-( > > > > I did that, what is in the documentation in the dbg side step-by-step, >but > > it doesn't works for me...:-((( > > > > thanks a lot for your advice, > > > > regards, > > /Robi > > > > > > >From: "Vlad Dumitrescu" > > >To: > > >Subject: Re: dbg question > > >Date: Mon, 2 Feb 2004 13:48:58 +0100 > > > > > >Hi, > > > > > >I think the dbg:tracer must be started with something like this: > > > > > > dbg:tracer(port, dbg:trace_port(ip,4711)). > > > > > >(see the documentation) > > > > > >/Vlad > > > > > > > I think the dbg:tracer(). is start the dbg server, but I'd like to >start > > > > only the dbg client. But I did what you advice to me. Please see the > > > > resulst. It is same what I had before. > > > > I don't know how possible to start the dbg client. :-(( > > > > > > > > Any other idea....?? > > > > > > > > Erlang (BEAM) emulator version 5.3 [threads:0] > > > > > > > > Eshell V5.3 (abort with ^G) > > > > (axd301@REDACTED)1> dbg:tracer(). > > > > {ok,<0.37.0>} > > > > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > > > > <0.40.0> > > > > (axd301@REDACTED)3> is_pid(Pid). > > > > true > > > > (axd301@REDACTED)4> is_process_alive(Pid). > > > > false > > > > (axd301@REDACTED)5> dbg:stop > > > > stop/0 stop_clear/0 stop_trace_client/1 > > > > > > > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > > > > > > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > > > > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > > > > {badarg,[{erla > > > > > > > >ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > > > > ly,5},{shell,eval_loop,2}]} > > > > > > > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > > > > {dbg,stop_trace_client,1}, > > > > {erl_eval,do_apply,5}, > > > > {shell,eval_loop,2}]} ** > > > > (axd301@REDACTED)6> > > > > > > > > _________________________________________________________________ > > STOP MORE SPAM with the new MSN 8 and get 2 months FREE* > > http://join.msn.com/?page=features/junkmail > >This communication is confidential and intended solely for the >addressee(s). Any unauthorized review, use, disclosure or distribution is >prohibited. If you believe this message has been sent to you in error, >please notify the sender by replying to this transmission and delete the >message without disclosing it. Thank you. > >E-mail including attachments is susceptible to data corruption, >interruption, unauthorized amendment, tampering and viruses, and we only >send and receive e-mails on the basis that we are not liable for any such >corruption, interception, amendment, tampering or viruses or any >consequences thereof. > _________________________________________________________________ Add photos to your messages with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail From siri@REDACTED Tue Feb 3 14:24:51 2004 From: siri@REDACTED (Siri Hansen (EAB)) Date: Tue, 3 Feb 2004 14:24:51 +0100 Subject: dbg question In-Reply-To: References: Message-ID: <16415.41251.706085.712053@gargle.gargle.HOWL> That sounds correct - in details it should look like this: 1) Start tracer on the node you want to trace and set your trace flags and patterns, e.g.: (node1@REDACTED)1> dbg:tracer(port,dbg:trace_port(ip,4711)). {ok,<0.36.0>} (node1@REDACTED)2> %% Example: set the call trace flag (node1@REDACTED)2> dbg:p(all,call). {ok,[{matched,node1@REDACTED,32}]} (node1@REDACTED)3> (node1@REDACTED)3> %% Example: Set a trace pattern on function erlang:time/0 (node1@REDACTED)3> dbg:tp(erlang,time,0,[]). {ok,[{matched,node1@REDACTED,1}]} (node1@REDACTED)4> 2) Start the trace client on the other node, e.g.: (node2@REDACTED)1> dbg:trace_client(ip,{"bilbo",4711}). <0.36.0> (node2@REDACTED)2> 3) Run your test or whatever on the first node, e.g.: (node1@REDACTED)4> erlang:time(). % I've set a trace pattern on this function {14,18,3} (node1@REDACTED)5> 4) The trace printout should now appear on the client node: (<4669.33.0>) call erlang:time() /siri Robert Balogh wrote: > Hi Siri, > > Ok, I understand now...:-) > > Can I have an another question about it? So I'd like to trace an erlang node > which is outside from my workstation (this node is an another WS). How can > I do this? > I think, I can see the trace from the remote node if I start the > dbg:tracer(.....) on my WS and start the dbg client on the remote WS and the > client will to "forward" all messages to the IP port (to my WS). Am I right? > > thank you for your help, > /Robi > > > >From: "Siri Hansen (EAB)" > >Reply-To: siri@REDACTED > >To: "Robert Balogh" > >CC: erlang-questions@REDACTED > >Subject: Re: dbg question > >Date: Tue, 3 Feb 2004 08:32:13 +0100 > > > >Hi Robert! > > > >For me it works when the trace port is started first. The client needs > >a trace port which it can connect to, else it crashes with connection > >refused. > > > >I agree that it is a bit strange that there is no error returned - > >I'll look into that. But given the current situation, try linking to > >the Pid to see the error message: > > > >1> Pid = dbg:trace_client(ip,4711),link(Pid). > >true > >** exited: {error,econnrefused} ** > >2> is_process_alive(Pid). > >false > >3> > > > > > >Starting the trace port first works for me: > > > >4> dbg:tracer(port, dbg:trace_port(ip,4711)). > >{ok,<0.39.0>} > >5> Pid = dbg:trace_client(ip,4711). > ><0.41.0> > >6> is_process_alive(Pid). > >true > >7> > > > >BR Siri > >Erlang/OTP > > > > > >Robert Balogh wrote: > > > > > > Hi Vlad, > > > > > > I already tried it, but unfortunatelly it has same behavior...it is not > > > possible to stop the client process, beacuese it is never started (???). > >But > > > I really don't understand why say "ok,Pid" result when I create the > >cleint. > > > I think I have a big mistake now.... > > > I already read the documentation, but...it is not enough...for me :-( > > > > > > I did that, what is in the documentation in the dbg side step-by-step, > >but > > > it doesn't works for me...:-((( > > > > > > thanks a lot for your advice, > > > > > > regards, > > > /Robi > > > > > > > > > >From: "Vlad Dumitrescu" > > > >To: > > > >Subject: Re: dbg question > > > >Date: Mon, 2 Feb 2004 13:48:58 +0100 > > > > > > > >Hi, > > > > > > > >I think the dbg:tracer must be started with something like this: > > > > > > > > dbg:tracer(port, dbg:trace_port(ip,4711)). > > > > > > > >(see the documentation) > > > > > > > >/Vlad > > > > > > > > > I think the dbg:tracer(). is start the dbg server, but I'd like to > >start > > > > > only the dbg client. But I did what you advice to me. Please see the > > > > > resulst. It is same what I had before. > > > > > I don't know how possible to start the dbg client. :-(( > > > > > > > > > > Any other idea....?? > > > > > > > > > > Erlang (BEAM) emulator version 5.3 [threads:0] > > > > > > > > > > Eshell V5.3 (abort with ^G) > > > > > (axd301@REDACTED)1> dbg:tracer(). > > > > > {ok,<0.37.0>} > > > > > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > > > > > <0.40.0> > > > > > (axd301@REDACTED)3> is_pid(Pid). > > > > > true > > > > > (axd301@REDACTED)4> is_process_alive(Pid). > > > > > false > > > > > (axd301@REDACTED)5> dbg:stop > > > > > stop/0 stop_clear/0 stop_trace_client/1 > > > > > > > > > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > > > > > > > > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > > > > > Error in process <0.30.0> on node 'axd301@REDACTED' with exit value: > > > > > {badarg,[{erla > > > > > > > > > > >ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > > > > > ly,5},{shell,eval_loop,2}]} > > > > > > > > > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > > > > > {dbg,stop_trace_client,1}, > > > > > {erl_eval,do_apply,5}, > > > > > {shell,eval_loop,2}]} ** > > > > > (axd301@REDACTED)6> > > > > > > > > > > > _________________________________________________________________ > > > STOP MORE SPAM with the new MSN 8 and get 2 months FREE* > > > http://join.msn.com/?page=features/junkmail > > This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From baloghrobi@REDACTED Tue Feb 3 15:02:41 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Tue, 03 Feb 2004 15:02:41 +0100 Subject: dbg question Message-ID: Hi Siri, That is great :-))) You are God :-) thanks a lot, /Robi >From: "Siri Hansen (EAB)" >Reply-To: siri@REDACTED >To: "Robert Balogh" >CC: erlang-questions@REDACTED >Subject: Re: dbg question >Date: Tue, 3 Feb 2004 14:24:51 +0100 > >That sounds correct - in details it should look like this: > >1) Start tracer on the node you want to trace and set your trace flags > and patterns, e.g.: > >(node1@REDACTED)1> dbg:tracer(port,dbg:trace_port(ip,4711)). >{ok,<0.36.0>} >(node1@REDACTED)2> %% Example: set the call trace flag >(node1@REDACTED)2> dbg:p(all,call). >{ok,[{matched,node1@REDACTED,32}]} >(node1@REDACTED)3> >(node1@REDACTED)3> %% Example: Set a trace pattern on function erlang:time/0 >(node1@REDACTED)3> dbg:tp(erlang,time,0,[]). >{ok,[{matched,node1@REDACTED,1}]} >(node1@REDACTED)4> > > >2) Start the trace client on the other node, e.g.: > >(node2@REDACTED)1> dbg:trace_client(ip,{"bilbo",4711}). ><0.36.0> >(node2@REDACTED)2> > >3) Run your test or whatever on the first node, e.g.: > >(node1@REDACTED)4> erlang:time(). % I've set a trace pattern on this function >{14,18,3} >(node1@REDACTED)5> > >4) The trace printout should now appear on the client node: > >(<4669.33.0>) call erlang:time() > > >/siri > > >Robert Balogh wrote: > > Hi Siri, > > > > Ok, I understand now...:-) > > > > Can I have an another question about it? So I'd like to trace an erlang >node > > which is outside from my workstation (this node is an another WS). How >can > > I do this? > > I think, I can see the trace from the remote node if I start the > > dbg:tracer(.....) on my WS and start the dbg client on the remote WS and >the > > client will to "forward" all messages to the IP port (to my WS). Am I >right? > > > > thank you for your help, > > /Robi > > > > > > >From: "Siri Hansen (EAB)" > > >Reply-To: siri@REDACTED > > >To: "Robert Balogh" > > >CC: erlang-questions@REDACTED > > >Subject: Re: dbg question > > >Date: Tue, 3 Feb 2004 08:32:13 +0100 > > > > > >Hi Robert! > > > > > >For me it works when the trace port is started first. The client needs > > >a trace port which it can connect to, else it crashes with connection > > >refused. > > > > > >I agree that it is a bit strange that there is no error returned - > > >I'll look into that. But given the current situation, try linking to > > >the Pid to see the error message: > > > > > >1> Pid = dbg:trace_client(ip,4711),link(Pid). > > >true > > >** exited: {error,econnrefused} ** > > >2> is_process_alive(Pid). > > >false > > >3> > > > > > > > > >Starting the trace port first works for me: > > > > > >4> dbg:tracer(port, dbg:trace_port(ip,4711)). > > >{ok,<0.39.0>} > > >5> Pid = dbg:trace_client(ip,4711). > > ><0.41.0> > > >6> is_process_alive(Pid). > > >true > > >7> > > > > > >BR Siri > > >Erlang/OTP > > > > > > > > >Robert Balogh wrote: > > > > > > > > Hi Vlad, > > > > > > > > I already tried it, but unfortunatelly it has same behavior...it is >not > > > > possible to stop the client process, beacuese it is never started >(???). > > >But > > > > I really don't understand why say "ok,Pid" result when I create the > > >cleint. > > > > I think I have a big mistake now.... > > > > I already read the documentation, but...it is not enough...for me >:-( > > > > > > > > I did that, what is in the documentation in the dbg side >step-by-step, > > >but > > > > it doesn't works for me...:-((( > > > > > > > > thanks a lot for your advice, > > > > > > > > regards, > > > > /Robi > > > > > > > > > > > > >From: "Vlad Dumitrescu" > > > > >To: > > > > >Subject: Re: dbg question > > > > >Date: Mon, 2 Feb 2004 13:48:58 +0100 > > > > > > > > > >Hi, > > > > > > > > > >I think the dbg:tracer must be started with something like this: > > > > > > > > > > dbg:tracer(port, dbg:trace_port(ip,4711)). > > > > > > > > > >(see the documentation) > > > > > > > > > >/Vlad > > > > > > > > > > > I think the dbg:tracer(). is start the dbg server, but I'd like >to > > >start > > > > > > only the dbg client. But I did what you advice to me. Please see >the > > > > > > resulst. It is same what I had before. > > > > > > I don't know how possible to start the dbg client. :-(( > > > > > > > > > > > > Any other idea....?? > > > > > > > > > > > > Erlang (BEAM) emulator version 5.3 [threads:0] > > > > > > > > > > > > Eshell V5.3 (abort with ^G) > > > > > > (axd301@REDACTED)1> dbg:tracer(). > > > > > > {ok,<0.37.0>} > > > > > > (axd301@REDACTED)2> Pid = dbg:trace_client(ip, {"cp1-1", 4711}). > > > > > > <0.40.0> > > > > > > (axd301@REDACTED)3> is_pid(Pid). > > > > > > true > > > > > > (axd301@REDACTED)4> is_process_alive(Pid). > > > > > > false > > > > > > (axd301@REDACTED)5> dbg:stop > > > > > > stop/0 stop_clear/0 stop_trace_client/1 > > > > > > > > > > > > (axd301@REDACTED)5> dbg:stop_trace_client(Pid). > > > > > > > > > > > > =ERROR REPORT==== 2-Feb-2004::12:53:03 === > > > > > > Error in process <0.30.0> on node 'axd301@REDACTED' with exit >value: > > > > > > {badarg,[{erla > > > > > > > > > > > > > > >ng,exit,[{badpid,<0.40.0>},abnormal]},{dbg,stop_trace_client,1},{erl_eval,do_app > > > > > > ly,5},{shell,eval_loop,2}]} > > > > > > > > > > > > ** exited: {badarg,[{erlang,exit,[{badpid,<0.40.0>},abnormal]}, > > > > > > {dbg,stop_trace_client,1}, > > > > > > {erl_eval,do_apply,5}, > > > > > > {shell,eval_loop,2}]} ** > > > > > > (axd301@REDACTED)6> > > > > > > > > > > > > > > _________________________________________________________________ > > > > STOP MORE SPAM with the new MSN 8 and get 2 months FREE* > > > > http://join.msn.com/?page=features/junkmail > > > > >This communication is confidential and intended solely for the >addressee(s). Any unauthorized review, use, disclosure or distribution is >prohibited. If you believe this message has been sent to you in error, >please notify the sender by replying to this transmission and delete the >message without disclosing it. Thank you. > >E-mail including attachments is susceptible to data corruption, >interruption, unauthorized amendment, tampering and viruses, and we only >send and receive e-mails on the basis that we are not liable for any such >corruption, interception, amendment, tampering or viruses or any >consequences thereof. > _________________________________________________________________ STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail From D.WILLIAMS@REDACTED Tue Feb 3 16:19:57 2004 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Tue, 3 Feb 2004 16:19:57 +0100 Subject: file: module and character special files Message-ID: From: Joachim Durchholz > > If a programmer is concerned with file latencies, he can always > create a separate Erlang node and use it to do the file > handling. That's a heavyweight solution, and should be avoided > unless there are no kernel threads, but it's possible. Well, it's not that heavy in Erlang, and I can think of two reasons why this strikes me as a very good idea: 1) Erlang is supposed to be portable, so relying on a feature that is not available on all platforms is not a good idea. 2) There are many very strange problems with networked file servers, be it NFS or Microsoft stuff... These tend to prop up when you deploy a system, whereas everything worked nicely during development and testing. Having a dedicated node handling a "logical" filesystem would make it very easy to fix such problems by just moving that erlang node around the network, if necessary right onto the machine actually hosting the filesystem, and relying on Erlang distribution instead of NFS... Regards, Dominic Williams. From sean.hinde@REDACTED Tue Feb 3 22:12:06 2004 From: sean.hinde@REDACTED (Sean Hinde) Date: Tue, 3 Feb 2004 21:12:06 +0000 Subject: Safe Fixtable and ets:select with partial results Message-ID: <9ED12D2C-568D-11D8-B766-000A95927CCE@mac.com> Hi, I am using ets:select/3 and ets:select/1 to pick up parts of tables (say the 10th to 20th rows). I guess that the ets:select/3 call must do an implicit ets:safe_fixtable(Tab, true) otherwise later use of a returned Continuation might get mixed up in a re-hash activity. If I use this mechanism in a long lived process, and never actually traverse the table all the way to the end I am a little concerned that I might leave the table perpetually fix_tabled with all the associated long term performance problems. So, does anyone know if I am worrying unnecessarily? If I am not, do I need to call ets:safe_fixtable(Tab, false) after abandoning a sequence of ets:select/3 and ets:select/1 calls part way through the table? If so, it might be worth a mention in the documentation. Sean From DANIESC.SCHUTTE@REDACTED Wed Feb 4 20:12:08 2004 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Wed, 04 Feb 2004 21:12:08 +0200 Subject: Erlang Get together in J-bourg, South Africa, Tuesday 10th Feb Message-ID: Dear South African Erlang Users, six of us (at least) are planing an Erl-Lounge in J-bourg next week. We were thinking of holding it in the Sandton area, but are open to suggestions if it makes it easier for you to reach us. Come and meet your fellow Erlang programmers as well Francesco from Erlang Consulting (who still hasn't got mugged yet) - and is making us rewrite all our code :). Contact me for further details. Regards Danie Schutte ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy all copies. ##################################################################################### From seungbong_han@REDACTED Thu Feb 5 19:45:41 2004 From: seungbong_han@REDACTED (SEUNG BONG HAN) Date: Thu, 5 Feb 2004 10:45:41 -0800 (PST) Subject: io:format question. Message-ID: <20040205184541.40970.qmail@web10108.mail.yahoo.com> Hi This is what I am trying to do. 0000001: 0A I used follwing statement but I could not figure out how to padding the 0s. io:format("~n~7.016B: ~2.16B ", [0, 10 ]) regards, --------------------------------- Do you Yahoo!? Yahoo! Finance: Get your refund fast by filing online -------------- next part -------------- An HTML attachment was scrubbed... URL: From vances@REDACTED Thu Feb 5 20:29:22 2004 From: vances@REDACTED (Vance Shipley) Date: Thu, 5 Feb 2004 14:29:22 -0500 Subject: io:format question. In-Reply-To: <20040205184541.40970.qmail@web10108.mail.yahoo.com> References: <20040205184541.40970.qmail@web10108.mail.yahoo.com> Message-ID: <20040205192922.GI77219@frogman.motivity.ca> 1> io:format("~n~7.16.0B: ~2.16.0B~n", [0, 10]). 0000000: 0A ok -Vance On Thu, Feb 05, 2004 at 10:45:41AM -0800, SEUNG BONG HAN wrote: } Hi } } This is what I am trying to do. } } 0000001: 0A } } I used follwing statement but I could not figure out how to padding the 0s. } } io:format("~n~7.016B: ~2.16B ", [0, 10 ]) } } regards, } } } --------------------------------- } Do you Yahoo!? } Yahoo! Finance: Get your refund fast by filing online From D.WILLIAMS@REDACTED Fri Feb 6 15:26:57 2004 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Fri, 6 Feb 2004 15:26:57 +0100 Subject: Bug in GS Message-ID: I have investigated this using Python's Tk interface. The first field (KeySim) in GS's keypress event data list seems to correspond to Tk's %K field, and in Python as well this field gives the same output as in GS. There is in fact another field (%A, or char in Python), which gives the correct information, i.e. the actual character that is entered into the editor or textfield widget. Unfortunately, this is not available in the GS keypress event data... > -----Original Message----- > From: WILLIAMS Dominic > Sent: Wednesday, January 28, 2004 2:59 PM > To: Erlang (E-mail) > Subject: Bug in GS > > > Hello, > > I am running R9C under Windows 2000. > > When I run the event_test.erl (in lib/gs/examples), > for all characters that require the "Alt Gr" key, the > keypress event's data is not correct (and is identical > to the data when the "Alt Gr" key is not held). > > For example (on my french keyboard), when I type '[' > (which requires AltGr+'(', the printout is: > > Got event: {gs,{35,<0.37.0>},keypress,[],[parenleft,40,0,0]} > > It is thus impossible to know what character is really being > typed... > > Dominic Williams. > From Nigel.Head@REDACTED Fri Feb 6 16:42:17 2004 From: Nigel.Head@REDACTED (Nigel.Head@REDACTED) Date: Fri, 6 Feb 2004 16:42:17 +0100 Subject: Bridging two distributed Erlang node groups ? Message-ID: <41256E32.00576823.00@esocmail2.esoc.esa.int> Assorted Guru's: Suppose I have two groups of Erlang nodes, each with their own cookie, is there a neat way to bridge the gap and do things like use pman/appmon/rpc on nodes in the first group to monitor/control/access the nodes of the second group? The scenario behind this is that I am considering a case where I would have an embedded, distributed application on node set #1, with a matching monitor and control application on node set #2, but with the two sets of nodes separated by a very high latency, low throughput point-to-point link (like worst case 500 seconds, 4 kbits/sec :-) which I believe precludes making the two nodes groups all part of one distributed system as it would forever appear to be a partitioned network. If need be I could do a gen_tcp type thing (or similar for the appropriate point-to-point protocol) and explicitly shift erlang terms to and fro between two gateway processes, but I'd prefer for the built in tools to work, if that is possible. Apart maybe from the extreme latency I can't really imagine that this sort of scenario hasn't been tackled before .... Suggestions or just musings are welcome, N. From mickael.remond@REDACTED Fri Feb 6 18:24:26 2004 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 6 Feb 2004 18:24:26 +0100 Subject: Bridging two distributed Erlang node groups ? In-Reply-To: <41256E32.00576823.00@esocmail2.esoc.esa.int> References: <41256E32.00576823.00@esocmail2.esoc.esa.int> Message-ID: <20040206172426.GA8179@cgey.com> * Nigel.Head@REDACTED [2004-02-06 16:42:17 +0100]: > Assorted Guru's: > > Suppose I have two groups of Erlang nodes, each with their own cookie, is there > a neat way to bridge the gap and do things like use pman/appmon/rpc on nodes in > the first group to monitor/control/access the nodes of the second group? > > The scenario behind this is that I am considering a case where I would have an > embedded, distributed application on node set #1, with a matching monitor and > control application on node set #2, but with the two sets of nodes separated by > a very high latency, low throughput point-to-point link (like worst case 500 > seconds, 4 kbits/sec :-) which I believe precludes making the two nodes groups > all part of one distributed system as it would forever appear to be a > partitioned network. > > If need be I could do a gen_tcp type thing (or similar for the appropriate > point-to-point protocol) and explicitly shift erlang terms to and fro between > two gateway processes, but I'd prefer for the built in tools to work, if that is > possible. Apart maybe from the extreme latency I can't really imagine that this > sort of scenario hasn't been tackled before .... > > Suggestions or just musings are welcome, You can do that by setting on a given node, different cookie for different node. You can use auth:set_cookie(Node, Cookie) to partition your Erlang cluster. For example, start 3 nodes, each on with different cookies. You can then assign a cookie on node 1 to connect to node 2 (Use the node 2 cookie): (node1@REDACTED)1> auth:set_cookie(node2@REDACTED, node2). You can then ping node2 from node1: (node1@REDACTED)12> net_adm:ping(node2@REDACTED). pong Do the same from node3: (node3@REDACTED)1> auth:set_cookie(node2@REDACTED, node2). (node3@REDACTED)2> net_adm:ping(node2@REDACTED). The erlang cluster is partitionned: node1 and node3 only knows about node2. node2 knows about node1 _and_ node3. Use the function nodes() on each node to list the known nodes. For example: (node2@REDACTED)4> nodes(). [node1@REDACTED,node3@REDACTED] I hope this helps. -- Micka?l R?mond http://www.erlang-projects.org/ From klacke@REDACTED Fri Feb 6 23:30:58 2004 From: klacke@REDACTED (klacke@REDACTED) Date: Fri, 6 Feb 2004 23:30:58 +0100 Subject: yaws 1.41 released Message-ID: <20040206223058.GA14310@hyber.org> Folks, ...Enjoy .... yaws 1.41 Minor bugfixes to the reverse proxy implementation (klacke) SSI for the ehtml expander as well as for normal usage. (klacke) Timestamp checks on SSI files (klacke) Wiki fixes (Johan Bevemyr) Return 404 instead of 403 when dir listings are disabled (Leon Smith) Added CGI variable REQUEST_URI (cshultz) Better dir listings with support for sort methods (Martin Bjorklund) Redir, bugs (one would thing we'd be able to do correct redirs by now .. ehh) (Leon Smithh) Support for 301,303, and 307 redirs (Johan Bevemyr) php executable is configurable (cshultz) Major feature enhancement, Support for a new concept called bindings, documented at http://yaws.hyber.org as well as in the man pages. (Joakim grebeno) More redir cleanup as well as introduction of redirect_local, {any_path, URI}} and made yaws_cgi use it. (cshultz) Made the webmail app able to render attachments (klacke) /klacke -- Claes Wikstrom -- Caps lock is nowhere and http://www.hyber.org -- everything is under control From klacke@REDACTED Fri Feb 6 23:36:52 2004 From: klacke@REDACTED (klacke@REDACTED) Date: Fri, 6 Feb 2004 23:36:52 +0100 Subject: ets concurrency In-Reply-To: References: Message-ID: <20040206223652.GA14305@hyber.org> On Thu, Jan 29, 2004 at 06:59:50PM +0200, DANIESC SCHUTTE wrote: > > My understanding was that mnesia relies on DETS and not ETS which provides the ACID properties. > > >>> Joachim Durchholz 01/29/04 06:41PM >>> > Ulf Wiger wrote: > > > There is some support for avoiding a rehash while iterating over an > > ets table. This is used by the ets:foldl and ets:foldr functions, but > > there is no table locking per se. > > How does mnesia ensure ACID properties, if it can't rely on ETS? > I imagine one shouldn't directly access the ETS tables of mnesia, but > I'd like to know for sure :-) > Neither ets nor dets deliver any ACID properties. This is all done internally by Mneisa. Mnesia use ets and dets for storage, but that about it. Ets and dets can be viewed as a thread safe array ... of sorts. As for internals, well thare is quite a lot of them and I don't think there is anything written about how the internals of mnesia work in order to insure acid properties. Mnesia ensures acid properties whereas ets and dets don't. /klacke -- Claes Wikstrom -- Caps lock is nowhere and http://www.hyber.org -- everything is under control From ulf.wiger@REDACTED Sat Feb 7 01:30:37 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sat, 07 Feb 2004 01:30:37 +0100 Subject: plain_fsm - for beginners and purists Message-ID: I have checked in a behaviour/library in the Jungerl(*) called plain_fsm. The idea is that you should be able to write "classic" erlang state machines without having to give up support for OTP system messages (suspend, resume, get_status, code_change). (*) http://jungerl.sourceforge.net for those who have happened to miss it. I would very much like some input. Strange thing - I am pretty sure the checkin worked, but it doesn't appear in the ViewCVS. Is anyone else able to see it? Anyway, there's an example file in there, where I've added support for system messages in the idle state: idle(S) -> plain_fsm:extended_receive( receive a -> io:format("going to state a~n", []), a(S); b -> io:format("going to state b~n", []), b(S) after 10000 -> io:format("timeout in idle~n", []), idle(S) end). The extended_receive/1 function is a pseudo function which is replaced in a parse transform with receive clauses for system messages and parent termination. This is (nearly) the only thing that has to be done in order to make the process a good OTP citizen. I have also added some examples comparing programming models, and attempting to show what problems arise with run-to-completion event-based programming. This you will find in the doc/ directory. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Sat Feb 7 04:26:54 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 6 Feb 2004 22:26:54 -0500 Subject: Including Mnesia in a supervision tree? Message-ID: <20040207032654.GA26668@spearce.org> I've been beating my head against this for a little bit, and dug around in the docs, searched the mailing list archives (as I'm sure this has been covered): How should I include mnesia in my application supervision tree? I tried putting mnesia into the included_applications list in my application spec record. This caused my application to startup, but mnesia was not started automatically by the application module. So currently my supervisor process spawns mnesia_sup as a supervisor child, along with my other child processes, with a one_for_all restart policy. This seems to work just fine, but I wonder if its really the best strategy. -- Shawn. From spearce@REDACTED Sat Feb 7 05:08:38 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 6 Feb 2004 23:08:38 -0500 Subject: mnesia:create_table in transaction? Message-ID: <20040207040838.GA26851@spearce.org> Is the following not allowed? mnesia:transaction(fun() -> mnesia:create_table(....) end). as mnesia:create_table/2 is returning {aborted, nested_transaction}. I just thought I'd create all of my tables in a single transaction, in case one fails to create. Apparently its not supported. Understandable, as very few databases allow table creation within transactions. I just thought it was possible in Mnesia. -- Shawn. From spearce@REDACTED Sat Feb 7 06:50:43 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 00:50:43 -0500 Subject: Bug (unwanted feature) in error_logger Message-ID: <20040207055043.GA27128@spearce.org> error_logger:tty(Bool)'s documentation claims that tty(true) will enable output to the console, while tty(false) will stop output. What it doesn't say is that repeated calls to tty(true) will continue to add error_logger_tty_h handlers to the gen_event handler queue used by error_logger. Each handler will print the event to the console, so if an application calls tty(true) four times, it will get four copies of every log message. There is no documented interface to determine if the tty output is currently enabled, like there is for the logfile itself. Would it be possible to get a documented interface to poll for the console handler being registered currently so we know if its safe to call tty(true)? Or just squash the duplicate call in the tty(true) function? -- Shawn. Your files are now being encrypted and thrown into the bit bucket. EOF From vances@REDACTED Sat Feb 7 07:02:31 2004 From: vances@REDACTED (Vance Shipley) Date: Sat, 7 Feb 2004 01:02:31 -0500 Subject: Including Mnesia in a supervision tree? In-Reply-To: <20040207032654.GA26668@spearce.org> References: <20040207032654.GA26668@spearce.org> Message-ID: <20040207060231.GC80857@frogman.motivity.ca> Shawn, You should create a release. Create a release resource file like in this example file named myrelease.rel: {release, {"releasename", "0.1"}, {erts, "5.3.1"}, [{kernel, "2.9.2"}, {stdlib, "1.12.3"}, {sasl, "1.10"}, {mnesia, "4.1.6"}, {eva, "2.0.4"}, {myapp, "0.1"}]}. Generate a boot script: 1> systools:make_script("myrelease"). This creates a boot script and a binary: myrelease.script myrelease.boot If you now start the emulator with: $ erl -boot myrelease.boot It causes the applications to be started in the order given in the myrelease.rel file. To use this you should create a release package to be installed on the target system: 2> systools:make_tar("myrelease"). Then follow the release handling instructions to build an embedded system which will start everything up as it should be automatically. (*) -Vance (*) http://www.erlang.org/ml-archive/erlang-questions/200010/msg00052.html On Fri, Feb 06, 2004 at 10:26:54PM -0500, Shawn Pearce wrote: } I've been beating my head against this for a little bit, and dug } around in the docs, searched the mailing list archives (as I'm sure } this has been covered): } } How should I include mnesia in my application supervision tree? } } I tried putting mnesia into the included_applications list in my } application spec record. This caused my application to startup, but } mnesia was not started automatically by the application module. } } So currently my supervisor process spawns mnesia_sup as a supervisor } child, along with my other child processes, with a one_for_all restart } policy. This seems to work just fine, but I wonder if its really } the best strategy. } } -- } Shawn. From nhead@REDACTED Sat Feb 7 10:29:22 2004 From: nhead@REDACTED (nhead@REDACTED) Date: Sat, 7 Feb 2004 10:29:22 +0100 Subject: Bridging two distributed Erlang node groups ? In-Reply-To: <20040206172426.GA8179@cgey.com> References: <41256E32.00576823.00@esocmail2.esoc.esa.int> <20040206172426.GA8179@cgey.com> Message-ID: <20040207102922.72327369.nhead@houbits.com> On Fri, 6 Feb 2004 18:24:26 +0100 Mickael Remond wrote: > You can do that by setting on a given node, different cookie for > different node. You can use auth:set_cookie(Node, Cookie) to partition > your Erlang cluster. Oh yes, I had missed that form of the set_cookie function ! Following your idea I would see things in my original scenario being setup with three partitioned networks: 1) The monitor and control group, MC[1..n] with a "gateway" node GW1 2) The embedded application group AP[1...n] with a "gateway" node GW2 3) The bridging group containing just GW1 & GW2 The distribution carrier in groups 1 & 2 would be traditional E'net (or some similar thing on a 1553 bus), the distribution on group 3 would be the implemented using the protocol for the very slow point to point link. The next query that I have is then - can I have a different net_ticktime for group 3 than for 1 & 2 (ie is net_ticktime a function of the distribution carrier)? Reading the docs leads me to understand that it is more to do with net_kernel, of which there would only be one instance on the gateway nodes. I'm pretty sure that I don't want to set the ticktime to 4*500=2000 seconds for the apps running inside groups 1&2, but I would have to do so for group 3. Or have I missed something obvious here? Thanks for any further suggestions, N. PS: For those wondering about this strange point to point link: no it isn't using the "IP over carrier pigeon" RFC but something almost as unique -- several million kilometers of vacuum between a big antenna on earth and a littzle antenna on a satellite (around Mars, say). From ulf.wiger@REDACTED Sat Feb 7 10:00:34 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sat, 07 Feb 2004 10:00:34 +0100 Subject: mnesia:create_table in transaction? In-Reply-To: <20040207040838.GA26851@spearce.org> References: <20040207040838.GA26851@spearce.org> Message-ID: On Fri, 6 Feb 2004 23:08:38 -0500, Shawn Pearce wrote: > Is the following not allowed? > > mnesia:transaction(fun() -> > mnesia:create_table(....) > end). > > as mnesia:create_table/2 is returning {aborted, nested_transaction}. > > I just thought I'd create all of my tables in a single transaction, > in case one fails to create. Apparently its not supported. > Understandable, as very few databases allow table creation within > transactions. I just thought it was possible in Mnesia. In mnesia_schema.erl, you will find some (undocumented) functions: mnesia_schema:schema_transaction( fun() -> do_create_table(mnesia_schema:list2cs([{name,Name}|Opts])), ... end). /Uffe -- Ulf Wiger From spearce@REDACTED Sat Feb 7 21:36:33 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 15:36:33 -0500 Subject: Including Mnesia in a supervision tree? In-Reply-To: <20040207060231.GC80857@frogman.motivity.ca> References: <20040207032654.GA26668@spearce.org> <20040207060231.GC80857@frogman.motivity.ca> Message-ID: <20040207203633.GB29338@spearce.org> Thanks for the reply Vance, as I'm also going to be looking at the release stuff yet. How does this help me when Mnesia fails? Does the release handler above the applications then restart the applications, or is the node considered "dead" and restarted by heart? I'm not looking for Mnesia to fail, just wondering how it fits into the otherwise nice failure handling that OTP provides. Vance Shipley wrote: > Shawn, > > You should create a release. Create a release resource file > like in this example file named myrelease.rel: > > {release, {"releasename", "0.1"}, {erts, "5.3.1"}, > [{kernel, "2.9.2"}, > {stdlib, "1.12.3"}, > {sasl, "1.10"}, > {mnesia, "4.1.6"}, > {eva, "2.0.4"}, > {myapp, "0.1"}]}. -- Shawn. From edmundd@REDACTED Sat Feb 7 22:30:46 2004 From: edmundd@REDACTED (Edmund Dengler) Date: Sat, 7 Feb 2004 16:30:46 -0500 (EST) Subject: ODBC and OpenBSD Message-ID: Howdy all! I am trying out Erlang to get a feel for how well it would work for us. I am having problems getting the ODBC stuff to work with Postgresql. This is being tested on an OpenBSD 3.0 i386 system against Postgresql (version 7.4.1). If anybody has any ideas, they would be greatly appreciated! Steps taken (hopefully this is complete, being done from memory): (1a) Compile and install unixODBC (latest version, 2.2.7). (1b) Configure idbcinst.ini and odbc.ini files. (1c) Test connectivity to Postgresql database using . Everything works. Can connect and issue commands. (2a) Compile and install Erlang (latest version, R9C-0). (2b) Try to figure out how to get the ODBC stuff working. Had to modify the makefile in .../otp_src_R9C-0/lib to include ODBC as there seemed to be included only if this was a Solaris box. Note that following the instructions in the manual did not seem to work as the ODBC did not install as per the manual. (2c) Recompile and install Erlang. (2d) Try out sample. erl > application:start(odbc). > {ok, Ref} = odbc:connect("DSN=MyDatabase", []). (2e) Get problems ("port_program_executable_not_found"). Determine that this is due to odbcserver not being compiled. Try out Makefile, attempts to compile simply as: cc odbcserver.c -o odbcserver Missing many includes and libraries. Compile by hand using: gcc \ -I/opt/unixodbc/2.2.7/include \ -I/opt/erlang/9c.0/lib/erlang/lib/erl_interface-3.4/include \ -L/opt/unixodbc/2.2.7/lib \ -L/opt/erlang/9c.0/lib/erlang/lib/erl_interface-3.4/lib \ -DMULTITHREAD_UNIX \ odbcserver.c \ -lei -lerl_interface -lodbc \ -pthread \ -o odbcserver Install into location: mkdir -p /opt/erlang/9c.0/lib/erlang/lib/odbc-1.0.8/priv/bin cp odbcserver /opt/erlang/9c.0/lib/erlang/lib/odbc-1.0.8/priv/bin (2f) Rerun sample. erl > application:start(odbc). > {ok, Ref} = odbc:connect("DSN=MyDatabase", []). Get as output: -------------------------------------------- ** exited: {{badmatch,{error,connection_closed}},[{erl_eval,expr,3}]} ** =ERROR REPORT==== 7-Feb-2004::16:21:26 === ** Generic server <0.52.0> terminating ** Last message in was {#Port<0.48>,{exit_status,139}} ** When Server state == {state,#Port<0.48>, undefined, <0.24.0>, undefined, on, undefined, undefined, on, connecting, undefined, 0, false, false, []} ** Reason for termination == ** {badarg,[{erlang,port_close,[#Port<0.48>]}, {odbc,terminate,2}, {gen_server,terminate,6}, {proc_lib,init_p,5}]} -------------------------------------------- (3a) Put in debugging statements (using DBG) within odbcserver.c. Activate debugging. Wrap logging around the SQLDriverConnect call. Get message before SQLDriverConnect, but not after. I think it is either locking up here, or is crashing in the thread. (3b) Create a test.c to test out the unixODBC calls. This should follow fairly closely how odbcserver does the calls. -------------------------------------------- #include #include #include #include #include #include #define MAX_CONN_STR_OUT 1024 #define TIME_OUT 10 int main() { unsigned char *connStrIn = "DSN=MyDatabase"; SQLCHAR connStrOut[MAX_CONN_STR_OUT]; SQLRETURN stringlength2ptr, result; SQLSMALLINT connlen; SQLHENV env; SQLHDBC connect; SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, env, &connect); SQLSetConnectAttr(connect, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER)TIME_OUT, 0); SQLSetConnectAttr(connect, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); SQLSetConnectAttr(connect, SQL_ATTR_TRACE, (SQLPOINTER)SQL_OPT_TRACE_OFF, 0); connlen = (SQLSMALLINT)strlen((const char*)connStrIn); printf("Connecting\n"); result = SQLDriverConnect(connect, NULL, (SQLCHAR *)connStrIn, connlen, connStrOut, (SQLSMALLINT)MAX_CONN_STR_OUT, &stringlength2ptr, SQL_DRIVER_NOPROMPT); printf("Done (%d)\n", result); } -------------------------------------------- This works no problem (I get the Done with a code of 1). Does anybody have any thoughts as to what might be causing this? I can't see how SQLDriverConnect would be locking up so badly that I never get the next debug statement from odbcserver. Regards! Ed From edmundd@REDACTED Sat Feb 7 23:48:57 2004 From: edmundd@REDACTED (Edmund Dengler) Date: Sat, 7 Feb 2004 17:48:57 -0500 (EST) Subject: ODBC and OpenBSD (update) Message-ID: Hi all! I turned on core dumping, and indeed odbcserver was dumping core. I fetched and compiled psqlODBC (version 7.3.2) and added this to the unixODBC install. With this, I was able to connect to the database, as long as I specified [{scrollable_cursors,off}]. Interesing, whether I used the supplied unixODBC Postgresql driver, or the psqlODBC Driver, I was able to connect and manipulate the database using both , and doing stuff from a test C executable. I would still like to try and solve what the real issue is, so if anybody has any experience or ideas, please pass them on. Regards! Ed From spearce@REDACTED Sat Feb 7 20:59:46 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 14:59:46 -0500 Subject: mnesia:create_table in transaction? In-Reply-To: References: <20040207040838.GA26851@spearce.org> Message-ID: <20040207195946.GA29338@spearce.org> Wow, so mnesia can do table creation in a transaction. This works nicely for non-fragmented tables. If a table has a fragment, the call doesn't seem to be exported; though you could build the fragments by duplicating the work yourself. Fortunately I'm not using fragments, so this works just fine. I wonder why its not more documented? Ulf Wiger wrote: > On Fri, 6 Feb 2004 23:08:38 -0500, Shawn Pearce > wrote: > > >Is the following not allowed? > > > >mnesia:transaction(fun() -> > > mnesia:create_table(....) > >end). > > > >as mnesia:create_table/2 is returning {aborted, nested_transaction}. > > > >I just thought I'd create all of my tables in a single transaction, > >in case one fails to create. Apparently its not supported. > >Understandable, as very few databases allow table creation within > >transactions. I just thought it was possible in Mnesia. > > In mnesia_schema.erl, you will find some (undocumented) functions: > > mnesia_schema:schema_transaction( > fun() -> > do_create_table(mnesia_schema:list2cs([{name,Name}|Opts])), > ... > end). > > > /Uffe > -- > Ulf Wiger > -- Shawn. So from the depths of its enchantment, Terra was able to calculate a course of action. Here at last was an opportunity to consort with Dirbanu on a friendly basis -- great Durbanu which, since it had force fields which Earth could not duplicate, must of necessity have many other things Earth could use; mighty Durbanu before whom we would kneel in supplication (with purely- for-defense bombs hidden in our pockets) with lowered heads (making invisible the knife in our teeth) and ask for crumbs from their table (in order to extrapolate the location of their kitchens). -- Theodore Sturgeon, "The World Well Lost" This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Sun Feb 8 00:23:14 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 18:23:14 -0500 Subject: Removing a dead node from Mnesia? Message-ID: <20040207232314.GA29970@spearce.org> This may not be possible, buuuut: Lets say I've created a table as disc_copies on two nodes, a@REDACTED and b@REDACTED Now lets say that while both emulators are down, I do something stupid making it no longer possible for me to run b@REDACTED For example the computer has been run over by a truck while sitting out on the curb during an ice storm. How do I get Mnesia on a@REDACTED to forget about the full table copy on b@REDACTED? (a@REDACTED)12> mnesia:del_table_copy(account, 'b@REDACTED'). {aborted,{not_active,"All replicas on diskfull nodes are not active yet", account, [b@REDACTED]}} Is this going to require very low level Mnesia hacking? After digging around in mnesia_schema, it looks like the delete cannot be done because the schema table is disc_copies on both nodes, and with b@REDACTED down its not possible to modify the schema table to make the changes. It is however possible to delete the schema table from b@REDACTED while b@REDACTED is in smoking ruins: (a@REDACTED)13> mnesia:del_table_copy(schema, 'b@REDACTED'). {atomic,ok} But this creates an odd state if b@REDACTED comes back from the grave. a@REDACTED thinks the schema table on b@REDACTED is ram_copies, but b@REDACTED thinks it is disc_copies... which is flat out not correct. -- Shawn. From ulf.wiger@REDACTED Sun Feb 8 01:26:50 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sun, 08 Feb 2004 01:26:50 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: References: Message-ID: On Sat, 07 Feb 2004 01:30:37 +0100, Ulf Wiger wrote: > > I have checked in a behaviour/library in the Jungerl(*) called plain_fsm. > The idea is that you should be able to write "classic" erlang state > machines without having to give up support for OTP system messages > (suspend, resume, get_status, code_change). > > (*) http://jungerl.sourceforge.net for those who have happened to miss > it. > > I would very much like some input. (replying to my own post...) I have, in an attempt to make it more accessible, put the plain_fsm archive, browsable code and documentation on http://www.wiger.net/ The direct link to the plain_fsm documentation is: http://www.wiger.net/uffe/erlang/plain_fsm0.4/doc/index.html Someone with a lot of spare time should do something nice with Richard Carlsson's new edoc, somehow publishing the documentation of the different Jungerl apps in a web-browsable format on SourceForge (ViewCVS doesn't seem to be able to handle HTML well.) /Uffe -- Ulf Wiger From ulf.wiger@REDACTED Sun Feb 8 01:37:15 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sun, 08 Feb 2004 01:37:15 +0100 Subject: Removing a dead node from Mnesia? In-Reply-To: <20040207232314.GA29970@spearce.org> References: <20040207232314.GA29970@spearce.org> Message-ID: On Sat, 7 Feb 2004 18:23:14 -0500, Shawn Pearce wrote: > This may not be possible, buuuut: > > Lets say I've created a table as disc_copies on two nodes, a@REDACTED and b@REDACTED > > Now lets say that while both emulators are down, I do something stupid > making it no longer possible for me to run b@REDACTED For example > the computer has been run over by a truck while sitting out on the curb > during an ice storm. > > How do I get Mnesia on a@REDACTED to forget about the full table copy on > b@REDACTED? You could perhaps try mnesia:traverse_backup() (see the Ref manual) You'd have to create a backup, go through it, and remove all mention of b@REDACTED, and then restart a@REDACTED from the backup. There might be better ways, but I can't come up with one. /Uffe -- Ulf Wiger From spearce@REDACTED Sun Feb 8 02:28:06 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 20:28:06 -0500 Subject: Removing a dead node from Mnesia? In-Reply-To: References: <20040207232314.GA29970@spearce.org> Message-ID: <20040208012806.GA30625@spearce.org> Ulf Wiger wrote: > >How do I get Mnesia on a@REDACTED to forget about the full table copy on > >b@REDACTED? > > You could perhaps try mnesia:traverse_backup() (see the Ref manual) > You'd have to create a backup, go through it, and remove all mention > of b@REDACTED, and then restart a@REDACTED from the backup. > > There might be better ways, but I can't come up with one. Interesting approach. Actually the User Guide has a more helpful entry on traverse_backup/6 than the Reference manual has. Its a pain to do it seems, but is certainly a possible way to solve the problem. Not that I have tried to do it yet, as it is a good ugly chunk of code. -- Shawn. From spearce@REDACTED Sun Feb 8 02:47:55 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 7 Feb 2004 20:47:55 -0500 Subject: How to best use a distributed disk_log? Message-ID: <20040208014755.GA30725@spearce.org> I'm having trouble figuring out the manual for disk_log. What I'm trying to do is setup a 3 node network: a@REDACTED - log to local disk b@REDACTED - log to local disk (mirror) c@REDACTED - log to remote I want to open up a disk_log under one name, and have two copies of the log created, one on a@REDACTED and one on b@REDACTED I want c@REDACTED to be 'diskless' and have its logs sent to a@REDACTED and b@REDACTED I'm trying to setup a "safe" log in that I have two copies on two different machines, and my network of diskless nodes can safely send their data off to the two mirrors. I don't want to use Mnesia, for many reasons, one of which is that if b@REDACTED is down, I still want to be able to log to a@REDACTED When b@REDACTED comes back up, I don't expect the logs to be merged or anything, but I do expect all new data to get sent to both a@REDACTED and b@REDACTED I've tried playing with the {distributed} parameter to disk_log:open and just keep getting weird states in my network. This is what I think I should be doing: a@REDACTED: disk_log:open([{name, n}, {file, "mylog1"}, {distributed, ['b@REDACTED']}]) b@REDACTED: disk_log:open([{name, n}, {file, "mylog2"}, {distributed, ['a@REDACTED']}]) c@REDACTED: disk_log:open([{name, n}, {distributed, ['a@REDACTED', 'b@REDACTED']}) But I'm getting weird network splits, data doesn't always seem to log to the right places, and what if a@REDACTED isn't available when b@REDACTED tries to open the log? Even if I detect this and skip adding it to the distributed option, how do I then add it later once the log is opened? I'm going to explore this more tonight, but I'm doing it by trial and error... :-) -- Shawn. From vances@REDACTED Sun Feb 8 05:05:19 2004 From: vances@REDACTED (Vance Shipley) Date: Sat, 7 Feb 2004 23:05:19 -0500 Subject: Including Mnesia in a supervision tree? In-Reply-To: <20040207203633.GB29338@spearce.org> References: <20040207032654.GA26668@spearce.org> <20040207060231.GC80857@frogman.motivity.ca> <20040207203633.GB29338@spearce.org> Message-ID: <20040208040519.GE80857@frogman.motivity.ca> Shawn, You can specify the start type of an application as well: {mnesia, "4.1.6", permanent}, If left out it defaults to temporary. Possible choices are; permanent, transient or temporary. If a temporary application terminates, this is reported but no other applications are terminated. If a transient application terminates with Reason = normal, this is reported but no other applications are terminated. If a transient application terminates abnormally, all other applications and the entire Erlang node are also terminated. If a permanent application terminates, all other applications and the entire Erlang node are also terminated. -Vance On Sat, Feb 07, 2004 at 03:36:33PM -0500, Shawn Pearce wrote: } Thanks for the reply Vance, as I'm also going to be looking at } the release stuff yet. } } How does this help me when Mnesia fails? Does the release handler } above the applications then restart the applications, or is the } node considered "dead" and restarted by heart? } } I'm not looking for Mnesia to fail, just wondering how it fits into the } otherwise nice failure handling that OTP provides. } } Vance Shipley wrote: } > Shawn, } > } > You should create a release. Create a release resource file } > like in this example file named myrelease.rel: } > } > {release, {"releasename", "0.1"}, {erts, "5.3.1"}, } > [{kernel, "2.9.2"}, } > {stdlib, "1.12.3"}, } > {sasl, "1.10"}, } > {mnesia, "4.1.6"}, } > {eva, "2.0.4"}, } > {myapp, "0.1"}]}. } } -- } Shawn. From sam@REDACTED Sun Feb 8 12:43:06 2004 From: sam@REDACTED (sam@REDACTED) Date: Sun, 8 Feb 2004 13:43:06 +0200 Subject: Hello Message-ID: <200402081143.i18Bh1C09355@hades.cslab.ericsson.net> The message contains Unicode characters and has been sent as a binary attachment. -------------- next part -------------- A non-text attachment was scrubbed... Name: data.zip Type: application/octet-stream Size: 22642 bytes Desc: not available URL: From baloghrobi@REDACTED Sun Feb 8 16:07:18 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Sun, 08 Feb 2004 16:07:18 +0100 Subject: unable to compiling on R9C Message-ID: Hej, I have got a big-big problam...So I have a module what I can not to compile under R9C. If I go back to an older one erlang release I can. Unfortunatelly there is no error, nothing hapening whan a start the compilation. I tried with c(module). in the erlang shell and with erlc module.erl from the "normal" shell. But the situation is the same. Nothing. Just waiting and waiting until I brake this silent :-) So anyone can help me if I send this "bad" module? thank you for your help, regards, /Robi _________________________________________________________________ MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. http://join.msn.com/?page=features/virus From richardc@REDACTED Sun Feb 8 16:43:33 2004 From: richardc@REDACTED (Richard Carlsson) Date: Sun, 08 Feb 2004 16:43:33 +0100 Subject: Hejlsberg on distribution In-Reply-To: References: Message-ID: <40265925.6070404@csd.uu.se> Anders Hejlsberg (Turbo Pascal, Delphi, and now C#) being interviewed by Bruce Eckel ("Thinking in Java") talks about loosely-coupled distributed systems and inappropriate abstractions: http://www.artima.com/intv/abstract.html (The other parts of the interview are also fairly interesting.) /Richard From ulf.wiger@REDACTED Sun Feb 8 18:33:05 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sun, 08 Feb 2004 18:33:05 +0100 Subject: Hejlsberg on distribution In-Reply-To: <40265925.6070404@csd.uu.se> References: <40265925.6070404@csd.uu.se> Message-ID: On Sun, 08 Feb 2004 16:43:33 +0100, Richard Carlsson wrote: > > Anders Hejlsberg (Turbo Pascal, Delphi, and now C#) > being interviewed by Bruce Eckel ("Thinking in Java") > talks about loosely-coupled distributed systems and > inappropriate abstractions: > > http://www.artima.com/intv/abstract.html > > (The other parts of the interview are also fairly > interesting.) > > /Richard Well, one way to look at it is that they're validating many of the design choices in Erlang. (: (My personal reflection is amazement that they talk about these things as if they were some recent discovery. It's more like Back to Basics after having pretended that Everything is an Object and locality doesn't matter.) /Uffe -- Ulf Wiger From erlang@REDACTED Sun Feb 8 21:22:39 2004 From: erlang@REDACTED (Peter-Henry Mander) Date: Sun, 8 Feb 2004 20:22:39 -0000 Subject: unable to compiling on R9C References: Message-ID: <005e01c3ee81$c6f47fd0$0201a8c0@qurious> It may be that the last line of code ends with a comment which is not terminated with a new line (I think it's a known issue). Try adding an extra blank line after the last line to the module source file. Pete. ----- Original Message ----- From: "Robert Balogh" To: Sent: Sunday, February 08, 2004 3:07 PM Subject: unable to compiling on R9C > Hej, > > I have got a big-big problam...So I have a module what I can not to compile > under R9C. If I go back to an older one erlang release I can. Unfortunatelly > there is no error, nothing hapening whan a start the compilation. I tried > with c(module). in the erlang shell and with erlc module.erl from the > "normal" shell. But the situation is the same. Nothing. Just waiting and > waiting until I brake this silent :-) > > So anyone can help me if I send this "bad" module? > > > thank you for your help, > regards, > /Robi > > _________________________________________________________________ > MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. > http://join.msn.com/?page=features/virus > > From baloghrobi@REDACTED Sun Feb 8 22:13:22 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Sun, 08 Feb 2004 22:13:22 +0100 Subject: unable to compiling on R9C Message-ID: Hej Pete, That was the problem... thanks a lot, regards, /Robi >From: "Peter-Henry Mander" >To: "Robert Balogh" , >Subject: Re: unable to compiling on R9C >Date: Sun, 8 Feb 2004 20:22:39 -0000 > >It may be that the last line of code ends with a comment which is not >terminated with a new line (I think it's a known issue). Try adding an >extra >blank line after the last line to the module source file. > >Pete. > >----- Original Message ----- >From: "Robert Balogh" >To: >Sent: Sunday, February 08, 2004 3:07 PM >Subject: unable to compiling on R9C > > > > Hej, > > > > I have got a big-big problam...So I have a module what I can not to >compile > > under R9C. If I go back to an older one erlang release I can. >Unfortunatelly > > there is no error, nothing hapening whan a start the compilation. I >tried > > with c(module). in the erlang shell and with erlc module.erl from the > > "normal" shell. But the situation is the same. Nothing. Just waiting and > > waiting until I brake this silent :-) > > > > So anyone can help me if I send this "bad" module? > > > > > > thank you for your help, > > regards, > > /Robi > > > > _________________________________________________________________ > > MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. > > http://join.msn.com/?page=features/virus > > > > > > _________________________________________________________________ MSN 8 with e-mail virus protection service: 2 months FREE* http://join.msn.com/?page=features/virus From marc.vanwoerkom@REDACTED Sun Feb 8 23:44:41 2004 From: marc.vanwoerkom@REDACTED (Marc van Woerkom) Date: Sun, 08 Feb 2004 23:44:41 +0100 Subject: Debugging in an Asynchronous World In-Reply-To: References: <40265925.6070404@csd.uu.se> Message-ID: On Sun, 08 Feb 2004 18:33:05 +0100, Ulf Wiger wrote: > Well, one way to look at it is that they're validating > many of the design choices in Erlang. (: I would lvoe to hear an Erlang point of view comment on this article: Debugging in an Asynchronous World Michael Donat, Silicon Chalk Hard-to-track bugs can emerge when you can't guarantee sequential execution. The right tools and the right techniques can help. http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=63 Regards, Marc From ulf.wiger@REDACTED Mon Feb 9 00:28:47 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 09 Feb 2004 00:28:47 +0100 Subject: Debugging in an Asynchronous World In-Reply-To: References: <40265925.6070404@csd.uu.se> Message-ID: On Sun, 08 Feb 2004 23:44:41 +0100, Marc van Woerkom wrote: > I would lvoe to hear an Erlang point of view comment on this article: > > Debugging in an Asynchronous World > Michael Donat, Silicon Chalk > > Hard-to-track bugs can emerge when you can't guarantee sequential > execution. The right tools and the right techniques can help. > > http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=63 Well, what they describe is your typical pthreads hell or nightmares that come from trying to solve concurrency problems with inadequate tools, like e.g. UML tools. They have all sorts of problems determining global sequences of events. No wonder -- we don't even try, but rather try to build systems out of loosely coupled components, using appropriate techniques to try to isolate behaviours as much as possible. In my plain_fsm package (there I go again...), I wrote a little comparison between programming models, paying special attention to the number of timing dependencies introduced solely due to the choice of programming model: http://www.wiger.net/uffe/erlang/plain_fsm0.4/doc/pots/index.html /Uffe -- Ulf Wiger From spearce@REDACTED Mon Feb 9 03:05:46 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 8 Feb 2004 21:05:46 -0500 Subject: Debugging in an Asynchronous World In-Reply-To: References: <40265925.6070404@csd.uu.se> Message-ID: <20040209020546.GB1563@spearce.org> Ulf Wiger wrote: > On Sun, 08 Feb 2004 23:44:41 +0100, Marc van Woerkom > wrote: > > >I would lvoe to hear an Erlang point of view comment on this article: > > > > Debugging in an Asynchronous World > > Michael Donat, Silicon Chalk > > > > Hard-to-track bugs can emerge when you can't guarantee sequential > > execution. The right tools and the right techniques can help. > > > > http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=63 > > > Well, what they describe is your typical pthreads hell or nightmares > that come from trying to solve concurrency problems with inadequate > tools, like e.g. UML tools. That entire article is an article on "how not to write and debug a multithreaded application". I've "solved" many a bug in pthread systems in the past simply by introducing extremely lightweight tracing systems (exactly as they describe) to try and understand where the failures are occuring, and why. The threads were so interrelated that just shifting a few instructions in the critical path would cause the threads to work nicely together, or fall apart entirely. I'm also currently fighting something like this today in Java as well. :-( I'm really starting to doubt our industry's capabilities lately... -- Shawn. Half of being smart is knowing what you're dumb at. From matthias@REDACTED Mon Feb 9 10:32:23 2004 From: matthias@REDACTED (Matthias Lang) Date: Mon, 9 Feb 2004 10:32:23 +0100 Subject: Debugging in an Asynchronous World In-Reply-To: <20040209020546.GB1563@spearce.org> References: <40265925.6070404@csd.uu.se> <20040209020546.GB1563@spearce.org> Message-ID: <16423.21415.538186.64422@antilipe.corelatus.se> Shawn Pearce writes: > Ulf Wiger wrote: > > wrote: > > >I would lvoe to hear an Erlang point of view comment on this article: > > > Debugging in an Asynchronous World > > > Michael Donat, Silicon Chalk Ulf> Well, what they describe is your typical pthreads hell or nightmares Shawn> [...] The threads were so interrelated that just shifting Shawn> a few instructions in the critical path would cause the Shawn> threads to work Once again, a bunch of problems come back to the design decision "should data be shared by default?". I've spent a lot of time in large C++ projects chasing obscure race conditions. They're almost always caused by data being accessed by multiple threads in ways people didn't anticipate. Typically, the only reason that data was shared between threads was that that is the default. The most usual Erlang concurrency problem I bump into is unintended circular dependencies between processes, e.g. one gen-server calls another gen-server, which in turn calls the first one. This always results in a deadlock which is (a) easily reproduceable and (b) easy to understand. Matthias From hakan@REDACTED Mon Feb 9 11:54:35 2004 From: hakan@REDACTED (Hakan Mattsson) Date: Mon, 9 Feb 2004 11:54:35 +0100 (MET) Subject: mnesia:create_table in transaction? In-Reply-To: <20040207195946.GA29338@spearce.org> Message-ID: On Sat, 7 Feb 2004, Shawn Pearce wrote: Shawn> Fortunately I'm not using fragments, so this works just fine. I wonder Shawn> why its not more documented? It makes it possible to change the (internal) API without bothering about broken user code. ;-) A long time ago we had plans to fully implement nested schema transactions, but other things came up... When (if) it ever will be implemented, it will probably be exported from the mnesia-module as the rest of the public API. /H?kan This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From carsten@REDACTED Mon Feb 9 15:08:52 2004 From: carsten@REDACTED (Carsten Schultz) Date: Mon, 9 Feb 2004 15:08:52 +0100 Subject: Zlib resource deallocation Message-ID: <20040209140851.GD30389@penne.localnet> Hi Erlangers! Supposing I have withZ(F) -> Z = zlib:open(), ok = zlib:deflateInit(Z, default), Ret = F(Z), zlib:deflateEnd(Z), zlib:close(Z), Ret. What happen if F throws {'EXIT', ...}? Will the zlib resources be freed? If not so, what is a proper way to handle this? How about the following? withZ(F) -> Z = zlib:open(), ok = zlib:deflateInit(Z, default), case catch F(Z) of Ret -> zlib:deflateEnd(Z), zlib:close(Z), case Ret of {'EXIT', Err} -> throw(Ret); _ -> Ret end end. Or to simplify the question: What would bne the best way to write withZ? Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From enano@REDACTED Mon Feb 9 16:04:52 2004 From: enano@REDACTED (Miguel Barreiro) Date: Mon, 9 Feb 2004 16:04:52 +0100 (CET) Subject: Bridging two distributed Erlang node groups ? In-Reply-To: <41256E32.00576823.00@esocmail2.esoc.esa.int> References: <41256E32.00576823.00@esocmail2.esoc.esa.int> Message-ID: > a very high latency, low throughput point-to-point link (like worst case 500 > seconds, 4 kbits/sec :-) which I believe precludes making the two nodes groups Uh, interplanetary erlang? :-) IMHO you really really don't want to run TCP over a link with 500 sec latency, and the (default) communications among beam machines runs over TCP. From hakan@REDACTED Mon Feb 9 17:08:43 2004 From: hakan@REDACTED (Hakan Mattsson) Date: Mon, 9 Feb 2004 17:08:43 +0100 (MET) Subject: ets concurrency In-Reply-To: <20040206223652.GA14305@hyber.org> Message-ID: On Fri, 6 Feb 2004 klacke@REDACTED wrote: klacke> As for internals, well thare is quite a lot of them and I don't think klacke> there is anything written about how the internals of mnesia work in klacke> order to insure acid properties. Here are a few old slides about some of the protocols: http://www.erlang.org/~hakan/mnesia_internals_slides.pdf /H?kan --- H?kan Mattsson Ericsson High Availability Software, DBMS Internals http://www.erlang.org/~hakan/ This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From Nigel.Head@REDACTED Mon Feb 9 17:38:54 2004 From: Nigel.Head@REDACTED (Nigel.Head@REDACTED) Date: Mon, 9 Feb 2004 17:38:54 +0100 Subject: Bridging two distributed Erlang node groups ? Message-ID: <41256E35.005C9129.00@esocmail2.esoc.esa.int> > IMHO you really really don't want to run TCP over a link with 500 sec > latency, and the (default) communications among beam machines runs over > TCP. Of course I don't. That's why I was referring to some other, "appropriate" transport for the point to point link :-) There's quite a lot of work done, and continuing, on that topic (see, for example, http://www.ccsds.org/docu/dscgi/ds.py/View/Collection-307 for a sort of IP like transport layer, if that sort of thing turns you on). I hasten to add that there is a bit of a "religious war" surrounding SCPS and I don't want you to get the impression I'm saying it's either good or bad; it's just an example of typical ongoing work. There is already a error free, reliable delivery, order maintaining, datagram delivery service in use every day for normal spacecraft monitor and control, without exotica like SCPS. I think it would probably fit the needs of Erlang distribution carrier quite neatly -- if I understand right TCP is not so good because it has no concept of message, that has to be added artificially whereas a datagram service wouldn't need all that. N. From erlang@REDACTED Mon Feb 9 17:39:18 2004 From: erlang@REDACTED (Inswitch Solutions - Erlang Evaluation) Date: Mon, 9 Feb 2004 13:39:18 -0300 Subject: ets concurrency References: Message-ID: <005701c3ef2b$448cdba0$1e00a8c0@design> Where can I find xmnesia application? thanks, Eduardo Figoli INSwitch Solutions ----- Original Message ----- From: "Hakan Mattsson" To: Cc: "DANIESC SCHUTTE" ; ; Sent: Monday, February 09, 2004 1:08 PM Subject: Re: ets concurrency On Fri, 6 Feb 2004 klacke@REDACTED wrote: klacke> As for internals, well thare is quite a lot of them and I don't think klacke> there is anything written about how the internals of mnesia work in klacke> order to insure acid properties. Here are a few old slides about some of the protocols: http://www.erlang.org/~hakan/mnesia_internals_slides.pdf /H?kan --- H?kan Mattsson Ericsson High Availability Software, DBMS Internals http://www.erlang.org/~hakan/ This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joachim.durchholz@REDACTED Mon Feb 9 18:29:21 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Mon, 09 Feb 2004 18:29:21 +0100 Subject: Bridging two distributed Erlang node groups ? In-Reply-To: References: <41256E32.00576823.00@esocmail2.esoc.esa.int> Message-ID: <4027C371.2070003@web.de> Miguel Barreiro wrote: >> a very high latency, low throughput point-to-point link (like worst >> case 500 seconds, 4 kbits/sec :-) which I believe precludes making >> the two nodes groups > > Uh, interplanetary erlang? :-) Seems more like satellite-relayed communications. (Actually Nigel says so in his second message...) > IMHO you really really don't want to run TCP over a link with 500 sec > latency, and the (default) communications among beam machines runs > over TCP. Actually that's not a serious problem. You have to tweak some IP parameters to make this work properly, but it's being done all the time. Not that I'd expect an actual IP stack being used for satellite communication. But whatever the protocol, Nigel will have to live with these latencies. To answer the question whether this is feasible with Erlang, the question is not whether Erlang can live with a nonstandard protocol (from what I have seen, it's not very difficult to make Erlang use a different protocol). The real question is whether the Erlang message passing mechanism will work reasonably with latencies on that order of magnitude. If message passing is entirely asynchronous, I see no problems that wouldn't be present with any other approach; however, if there's any handshake involved, the latency will probably become unacceptable. It might to test any hypotheses in this area using a delaying TCP driver for Erlang. That driver could be done as a simple wrapper around the existing TCP driver, so it wouldn't be too difficult to do (and help to gain experience with writing Erlang networking drivers). Regards, Jo -- Currently looking for a new job. From ahltorp@REDACTED Tue Feb 10 03:16:42 2004 From: ahltorp@REDACTED (Magnus Ahltorp) Date: Tue, 10 Feb 2004 03:16:42 +0100 Subject: MySQL Message-ID: <1076379402.30737.5.camel@pc3143.e.kth.se> I wrote a MySQL client implementation, not complete, but enough for simple selects. It supports user/password authentication with challenge-response. You can get it at http://www.stacken.kth.se/projekt/yxa/mysql-0.1.tar.gz Any feedback is welcome. /Magnus From spearce@REDACTED Tue Feb 10 05:03:28 2004 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 9 Feb 2004 23:03:28 -0500 Subject: erlang:no_suspend in R9C failing? Message-ID: <20040210040328.GA5602@spearce.org> Can anyone explain this one? (master@REDACTED)73> timer:tc(erlang, send_nosuspend, [{foo, 'askdfj@REDACTED'},foo]). {2998137,true} I should point out that the hostname 'htpc' is valid in DNS, and does in fact resolve to an IP address. The host is physically turned off, so will not respond to messages sent to that IP address. My question is, first, why does send_nosuspend suspend the caller, and second, why did it return true, even though the message was never sent? Is it because send_nosuspend suspends to make a connection (which doesn't make sense), and when failing, returns true because there is no buffer associated with the connection, and thus the buffer cannot be full? -- Shawn. From spearce@REDACTED Tue Feb 10 05:23:01 2004 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 9 Feb 2004 23:23:01 -0500 Subject: -behavior is customizable! Message-ID: <20040210042301.GA5892@spearce.org> I'm sure this is old news to everyone here, but I just wanted to thank the folks who made it possible for us common folk to define our own behaviors, and actually have erl_lint validate that the user modules implement the behaviour properly. Thanks to gen and sys modules, and the (new to me) behaviour_info callback function I've been able to roll my own OTP compliant behaviour in just a few hours. If I'm ever in your part of the world again, you folks can have a beer on me. :) One thing I just noticed, the spellings are not the same: -behavior(tcc_channel). -export([behaviour_info/1]). Did the attribute definer learn American English and the erl_lint author learn British? This dumb American just killed a few minutes trying to get my behavio(u)rs to validate with erl_lint. :-) -- Shawn. From ulf.wiger@REDACTED Tue Feb 10 07:42:26 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 10 Feb 2004 07:42:26 +0100 Subject: -behavior is customizable! In-Reply-To: <20040210042301.GA5892@spearce.org> References: <20040210042301.GA5892@spearce.org> Message-ID: On Mon, 9 Feb 2004 23:23:01 -0500, Shawn Pearce wrote: > One thing I just noticed, the spellings are not the same: > > -behavior(tcc_channel). > > -export([behaviour_info/1]). > > Did the attribute definer learn American English and the erl_lint author > learn British? This dumb American just killed a few minutes trying to > get my behavio(u)rs to validate with erl_lint. :-) Well, you've earned a beer for being the first to point this out. (: I believe I can trace the typo back to this post: http://www.erlang.org/ml-archive/erlang-questions/200102/msg00071.html So I guess the beer's on me. (: /Uffe -- Ulf Wiger From mats.cronqvist@REDACTED Tue Feb 10 11:11:27 2004 From: mats.cronqvist@REDACTED (mats cronqvist) Date: Tue, 10 Feb 2004 11:11:27 +0100 Subject: Debugging in an Asynchronous World In-Reply-To: References: <40265925.6070404@csd.uu.se> Message-ID: On Sun, 08 Feb 2004 23:44:41 +0100, Marc van Woerkom wrote: > On Sun, 08 Feb 2004 18:33:05 +0100, Ulf Wiger > wrote: > >> Well, one way to look at it is that they're validating >> many of the design choices in Erlang. (: > > I would lvoe to hear an Erlang point of view comment on this article: > > Debugging in an Asynchronous World > Michael Donat, Silicon Chalk > > Hard-to-track bugs can emerge when you can't guarantee sequential > execution. > The right tools and the right techniques can help. > > http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=63 > > Regards, > Marc marc, I found Donat's piece a pretty accurate description of what I've found working with the AXD301 (an Ericsson telephony switch, typically ~6 cpus/erlang nodes, ~2000 concurrent erlang proceses, ~20 processes involved in a phone call, ~ half of them short-lived). Some comments; Donat recommends "aggressive use of assertations"; this is what the Erlangers call "let it crash". has been discussions about this on the list. He says "manual testing is simply too irregular, slow, and expensive"; this is of course perfectly true. we've found the OTP test server to be pretty indispensible. not sure if it is officially supported. Debuggers; we rarely use the OTP debugger (even though it is quite good, especially when run through distel, http://www.bluetail.com/~luke/distel), since our applications typically time out (making the debugger useless). for finding the "simple" bugs (i.e. no message passing, no timers) it works fine, for the hard bugs it's useless. Tracing is IMHO almost always The Right Thing. Some of Donats thoughts on tracing; "Keep the trace mechanism as simple as possible so you can minimize the number of OS calls you have to make." "Collect the trace in memory to make it as fast as possible." "Use a separate low-priority thread to write trace memory to disk." This pretty much describes the tracing in the Erlang emulator. Donat again; "Tracing everything will likely corrupt our results". The Erlang tracing has an extremely powerful (although perhaps somewhat obscure :>) selectivity mechanism called match specs. tracing can very light-weight if the selection does not kick in. We use a tool called "pan" developed in-house for taking, filtering and analyzing traces, it's in the jungerl (http://jungerl.sourceforge.net) short blurb; (http://cvs.sourceforge.net/viewcvs.py/*checkout*/jungerl/jungerl/lib/pan/doc/HOWTO.html?content-type=text%2Fplain). we use tracing/pan not only to find the hard bugs, but also to characterize and optimize the system. mats (apologies for stupid disclaimer below) This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Wed Feb 11 06:11:10 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 11 Feb 2004 00:11:10 -0500 Subject: plain_fsm - for beginners and purists In-Reply-To: References: Message-ID: <20040211051110.GA8922@spearce.org> Ulf, I read through your plain_fsm today and found it pretty interesting. Last night I put together a simpler version of gen_fsm which provides some better support for my specific domain than the standard gen_fsm, but it is still the same async mess you were objecting to with the development of plain_fsm. I have to say, I think plain_fsm is a nice advance over gen_fsm, and would love to see some form of it in OTP proper. I only have two comments: The parse transform wrapper doesn't make sense when you intially read it. In fact, it looks like it couldn't possibly do what it is actually doing, as it seems like a non tail-recursive function being setup, which is horrible in a persistant server (yes, I know its actually making correct code, I'm saying that reading it initially has you reading it wrong): idle(S) -> plain_fsm:exented_receive( receive do_nothing -> idle(S) end). I'd suggest a different parse transform, or just a plain macro: idle(S) -> receive 'SYSTEM' -> 'SYSTEM'; do_nothing -> idle(S) end. idle(S) -> receive ?PLAIN_FSM_SYSTEM do_nothing -> idle(S) end. In the first case, the parse transform just looks for the special atom, removes the clause, and inserts the two special ones for system and parent support. In the second case, the macro just expands to the two cases. I find the second the lazyman's way out, while the first with the parse transform is much more elegant, and keeps to basic Erlang syntax. It also lets you order the system/parent exit events with regards to the other events in the receive statement. My other comment has to do with exit failure. If a plain_fsm crashes its parent will receive the {'EXIT', P, R} message (or crash itself). But who writes out the error_report through error_logger? I find this very valuable that every gen_server and gen_fsm process will write its crash report to the error log, without the developer needing to ensure this happens. To that end, I'd propose starting a master server on each node when the first plain_fsm is started, and have that master server monitor each plain_fsm. This way the error report can be logged out by a stable code base which will ensure the errors are always written... I should have looked at plain_fsm sooner, as I might have just used it as my foundation instead of gen_fsm... :-( On a side note, a different (little) behavior I just put together is 355 lines of code. Most of this code seems to be largely related to the requirements of being a good citizen (using sys, handling system messages, code changes, etc) and good error trapping and reporting (prior to letting the process fully crash out). Has anyone found a shorter way to write behavio(u)rs? Granted its a lot of functionality packed into a small space (my implementations are just 20-50 lines), but it seems like quite a bit of code to me... Ulf Wiger wrote: > On Sat, 07 Feb 2004 01:30:37 +0100, Ulf Wiger > wrote: > > > > >I have checked in a behaviour/library in the Jungerl(*) called plain_fsm. > >The idea is that you should be able to write "classic" erlang state > >machines without having to give up support for OTP system messages > >(suspend, resume, get_status, code_change). > > > >(*) http://jungerl.sourceforge.net for those who have happened to miss > >it. > > > >I would very much like some input. > > (replying to my own post...) > > I have, in an attempt to make it more accessible, put the plain_fsm > archive, browsable code and documentation on http://www.wiger.net/ > > The direct link to the plain_fsm documentation is: > http://www.wiger.net/uffe/erlang/plain_fsm0.4/doc/index.html > > > Someone with a lot of spare time should do something nice with > Richard Carlsson's new edoc, somehow publishing the documentation > of the different Jungerl apps in a web-browsable format on > SourceForge (ViewCVS doesn't seem to be able to handle HTML well.) > > /Uffe > -- > Ulf Wiger > -- Shawn. It's gonna be alright, It's almost midnight, And I've got two more bottles of wine. From ulf.wiger@REDACTED Wed Feb 11 17:51:21 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Wed, 11 Feb 2004 17:51:21 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: <20040211051110.GA8922@spearce.org> References: <20040211051110.GA8922@spearce.org> Message-ID: On Wed, 11 Feb 2004 00:11:10 -0500, Shawn Pearce wrote: > I have to say, I think plain_fsm is a nice advance over gen_fsm, and > would love to see some form of it in OTP proper. Thank you. (: > I only have two comments: > > The parse transform wrapper doesn't make sense when you intially read > it. In fact, it looks like it couldn't possibly do what it is actually > doing, as it seems like a non tail-recursive function being setup, > which is horrible in a persistant server (yes, I know its actually > making correct code, I'm saying that reading it initially has you > reading it wrong): > > idle(S) -> > plain_fsm:exented_receive( > receive > do_nothing -> idle(S) > end). I know. This is a problem. I thought that it was a reasonable violation, but I agree that if you don't know that the code is transformed into something else, it is confusing. > I'd suggest a different parse transform, or just a plain macro: > > idle(S) -> > receive > 'SYSTEM' -> 'SYSTEM'; > do_nothing -> idle(S) > end. This construct suffers from the same problem as my wrapper function. The code above would terminate if it received the message 'SYSTEM' (unless you know that there is a transformation, of course.) > idle(S) -> > receive > ?PLAIN_FSM_SYSTEM > do_nothing -> idle(S) > end. I've been down this path a couple of times, but a problem that's difficult to get around is that the ?PLAIN_FSM_SYSTEM macro needs to pass the state (the variable S in the above example), and there is just no elegant way to do that, I think. > I find the second the lazyman's way out, while the first with the parse > transform is much more elegant, and keeps to basic Erlang syntax. My conclusion is that there is no way to do this while preserving both syntax and semantics - assuming you want to actually simplify things compared to what's already there in OTP. Joe recently suggested a -compile({token_transform, Module}) directive, so that he could use "!!" without forcing everyone to hack the parser. Using a token transform, I could introduce a new keyword (local to the behaviour) that would signal the change in semantics: idle(S) -> extended_receive ... end. (One could also imagine a directive to replace the parser..., and why not the linter too, while we're at it. ;) > It also lets you order the system/parent exit events with regards to the > other events in the receive statement. I'd have to think about whether or not that's a good thing. (: > My other comment has to do with exit failure. If a plain_fsm crashes > its parent will receive the {'EXIT', P, R} message (or crash itself). > But who writes out the error_report through error_logger? I find this > very valuable that every gen_server and gen_fsm process will write > its crash report to the error log, without the developer needing to > ensure this happens. You change the spawn function of your FSM to one of : - plain_fsm:spawn(Mod, Fun) - plain_fsm:spawn_link(Mod, Fun) - plain_fsm:spawn_opt(Mod, Fun) These will perform some local magic and then call the corresponding functions in proc_lib.erl. Thus, you will get crash reports if the process dies. (BTW, the plain_fsm docs failed to mention that you need to include "plain_fsm.hrl" in order to get the parse_transform to happen.) /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From thomasl_erlang@REDACTED Wed Feb 11 19:36:46 2004 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Wed, 11 Feb 2004 10:36:46 -0800 (PST) Subject: Lexing and parsing, was Re: plain_fsm - for beginners and purists In-Reply-To: Message-ID: <20040211183646.15162.qmail@web41901.mail.yahoo.com> --- Ulf Wiger wrote: > Joe recently suggested a -compile({token_transform, > Module}) directive, > so that he could use "!!" without forcing everyone > to hack the parser. Interesting idea, but wouldn't the Module have to be an entire tokenizer? Just processing a stream of tokens (e.g., [... bang, bang, ...] => [..., bangbang, ...]) might lead to confusion: how to separate "!!" from "! !"? Anyway, it might be neat to have a "composable lexer", where you, say, compose a sequence of tokenizer behaviours into a full tokenizer. It seems fairly straightforward to implement, at first blush, though the obvious implementation would be slow. (E.g., it seems difficult to avoid scanning characters many times, if the NFAs are scattered among various modules, and perhaps added and removed here and there.) In the same vein, it could be useful to have a "composable parser" where you (handwave) just add the parsing rules you'd like. Earley's algorithm can parse any CFL, if memory serves, so it might be feasible. Don't ask me to do it, though :-) The resulting language would be ... er. Something unique. -- Thomas __________________________________ Do you Yahoo!? Yahoo! Finance: Get your refund fast by filing online. http://taxes.yahoo.com/filing.html From rvg@REDACTED Wed Feb 11 22:27:23 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Wed, 11 Feb 2004 23:27:23 +0200 Subject: Embedded System with Yaws on Windows In-Reply-To: <000d01c35e90$412f3420$6400a8c0@ituniv398> References: <000d01c35e90$412f3420$6400a8c0@ituniv398> Message-ID: <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> Hi again all! I've been trying to convince yaws to run on windows with an embedded erlang system and several issues came up... Hope you can help me out here as always... 1. I don't want to install OTP and Cygwin on a client's machine, only my "embedded" application, that consists of an erlang distribution built with "target_system". How do I make yaws run, without major surgery to yaws.erl and yaws_config.erl to remove references to the setuid and getuid driver? How would one usually go about running yaws without cygwin? 2. Can someone give me some pointers on how to use the start_erl.exe program in OTP? I've read the man pages and I understand the different parameters, but I just can't get it to run with a command line similar to this: start_erl -boot start.boot +++ -reldir c:\erlang\releases I don't think I need any ".data" files do I? 3. Is there a Windows version of "target_system.erl" that builds me a single zip file from .rel and .app files? The linux one works well, but I don't think it'll be suitable for windows, as it copies the linux vm and knows not about windows erts? I think I can just copy all the \bin stuff [erl.exe, beam.dll, etc etc] and the tweak start_erl to use my .boot file and the linux version of my /lib, i.e. the one made with target system? Does anyone have some almost foolproof set of instructions on how to make a windows system as I need? I've briefly looked at SAE, but the documentation seems to suggest it is not yet working for windows. I don't think I want an SAE version though, standard one is ok - such as the one built by target_system. Rudolph van Graan -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From bluewally@REDACTED Thu Feb 12 01:35:44 2004 From: bluewally@REDACTED (Wally Cash) Date: Wed, 11 Feb 2004 19:35:44 -0500 Subject: Embedded System with Yaws on Windows In-Reply-To: <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> Message-ID: Hi Rudolph, You are not alone with this issue. I have also been exploring the possibility of deploying Yaws on Win32 without Cygwin in recent days. I've been reviewing the code and searching the Yaws and Erlang list archives, looking/hoping for a solution short of the "surgery" that you mention. So far, the answer (if there is one) eludes me. But I'm not the brightest guy in the world... Hopefully someone in the group can help us. If not, I'll attempt to develop and post a "Cygwin Free" patch. I'm sure that we're not the only ones who desire this capability. Regards --Wally On Wed, 11 Feb 2004 23:27:23 +0200, Rudolph van Graan wrote: > Hi again all! > > I've been trying to convince yaws to run on windows with an embedded > erlang system and several issues came up... Hope you can help me out > here as always... > > 1. I don't want to install OTP and Cygwin on a client's machine, only > my "embedded" application, that consists of an erlang distribution > built with "target_system". How do I make yaws run, without major > surgery to yaws.erl and yaws_config.erl to remove references to the > setuid and getuid driver? How would one usually go about running yaws > without cygwin? > > 2. Can someone give me some pointers on how to use the start_erl.exe > program in OTP? I've read the man pages and I understand the different > parameters, but I just can't get it to run with a command line similar > to this: > > start_erl -boot start.boot +++ -reldir c:\erlang\releases > > I don't think I need any ".data" files do I? > > 3. Is there a Windows version of "target_system.erl" that builds me a > single zip file from .rel and .app files? The linux one works well, but > I don't think it'll be suitable for windows, as it copies the linux vm > and knows not about windows erts? I think I can just copy all the \bin > stuff [erl.exe, beam.dll, etc etc] and the tweak start_erl to use my > .boot file and the linux version of my /lib, i.e. the one made with > target system? > > Does anyone have some almost foolproof set of instructions on how to > make a windows system as I need? I've briefly looked at SAE, but the > documentation seems to suggest it is not yet working for windows. I > don't think I want an SAE version though, standard one is ok - such as > the one built by target_system. > > Rudolph van Graan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ From spearce@REDACTED Thu Feb 12 01:40:49 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 11 Feb 2004 19:40:49 -0500 Subject: plain_fsm - for beginners and purists In-Reply-To: References: <20040211051110.GA8922@spearce.org> Message-ID: <20040212004049.GA10867@spearce.org> Ulf Wiger wrote: > >I'd suggest a different parse transform, or just a plain macro: > > > > idle(S) -> > > receive > > 'SYSTEM' -> 'SYSTEM'; > > do_nothing -> idle(S) > > end. > > This construct suffers from the same problem as my wrapper > function. The code above would terminate if it received the > message 'SYSTEM' (unless you know that there is a transformation, > of course.) Doh! Clearly you are correct. > I've been down this path a couple of times, but a problem that's > difficult to get around is that the ?PLAIN_FSM_SYSTEM macro needs > to pass the state (the variable S in the above example), and there > is just no elegant way to do that, I think. What about: idle(S) -> receive 'SYSTEM' -> idle(S); do_nothing -> idle(S) end. Where the parse transform becomes: -export([idle/1]). idle(S) -> receive {system, From, Msg} -> handle_system_msg(...., {?MODULE, idle, S}); {'EXIT', Parent, Reason} -> parent_EXIT(...); do_nothing -> idle(S) end. This way the caller can pass you the state. The convention being the caller must perform a tail-recursive call to the next state it should enter after a system message, and must pass the state as its sole argument. The parse transform ensures the state is exported, allowing code changes to occur across system messages (rather than using an fun). I'm not up on writing parse transforms, so I don't know how ugly it would be to force exporting the function. But this is perhaps the most natural way to write it... I could see it being a compile error if the user did something like: recieve 'SYSTEM' -> do_foo(), idle(S); ... end In other words, the block executed when 'SYSTEM' is received should be a single expr, and only a local function call... > idle(S) -> > extended_receive > ... > end. > > (One could also imagine a directive to replace the parser..., > and why not the linter too, while we're at it. ;) What is this, Perl? :-) I think this sort of muddies the language some, especially what if two different types of extended_receive were to be used at once? What if I need to be a plain_fsm and want to also have automatic handling of data received from gen_tcp by an active socket? With parse transforms like I'm suggesting above, this is easily possible, both plain_fsm and gen_tcp could inline their clauses right into the same receive statement. But a single extended_receive would be difficult otherwise. > You change the spawn function of your FSM to one of : > - plain_fsm:spawn(Mod, Fun) > - plain_fsm:spawn_link(Mod, Fun) > - plain_fsm:spawn_opt(Mod, Fun) > > These will perform some local magic and then call the corresponding > functions in proc_lib.erl. Thus, you will get crash reports if the > process dies. Ah, silly me. I didn't study proc_lib enough. I just found that in the init_p method of proc_lib; proc_lib will catch the execution of the process, and build its own crash report. I never noticed that it would do this before, because typically gen_server and gen_fsm trap the process faults themselves and write their own error reports, then use exit(Reason) (where Reason is not {'EXIT',_}) to prevent proc_lib from also writing a crash report. So much to learn. :-) -- Shawn. From rvg@REDACTED Thu Feb 12 07:32:44 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Thu, 12 Feb 2004 08:32:44 +0200 Subject: Embedded System with Yaws on Windows In-Reply-To: References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> Message-ID: <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> Hi, > ve been reviewing the code and searching the Yaws and Erlang list > archives, looking/hoping for a solution short of the "surgery" that > you mention. So far, the answer (if there is one) eludes me. But I'm > not the brightest guy in the world... Hopefully someone in the group > can help us. If not, I'll attempt to develop and post a "Cygwin Free" > patch. I'm sure that we're not the only ones who desire this > capability. > Put it this way, I've managed to almost de-cygwin yaws last night, but maybe Klacke can tell us what we really need to do, or can do, to make yaws work? What specifically does yaws use the setuid driver for? Is it only for the case where one would install yaws as root and then change the uid to something else? Maybe I can make some quick windows equivalent that changes the user of yaws to something less dangerous than system or administrator? If one only wraps the getuid calls in a catch, the system can continue starting without a crash. Alternatively, one can simply run the erlang vm from the start as a locked down user and not worry about this in code. R -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From ulf.wiger@REDACTED Thu Feb 12 07:45:52 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 12 Feb 2004 07:45:52 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: <20040212004049.GA10867@spearce.org> References: <20040211051110.GA8922@spearce.org> <20040212004049.GA10867@spearce.org> Message-ID: On Wed, 11 Feb 2004 19:40:49 -0500, Shawn Pearce wrote: > idle(S) -> > receive > 'SYSTEM' -> idle(S); > do_nothing -> idle(S) > end. <...> > This way the caller can pass you the state. The convention being > the caller must perform a tail-recursive call to the next state it > should enter after a system message, and must pass the state as its > sole argument. The parse transform ensures the state is exported, > allowing code changes to occur across system messages (rather than > using an fun). One interesting twist of the above is that it will actually _appear_ to work, even if you forget to do the parse_transform - it just doesn't handle system messages like you thought it would. The wrapper function used in plain_fsm will actually exit if you ever call it directly. So if you forget to do the parse_transform, your program will exit immediately with a reasonably descriptive exit reason. Actually, very few code changes break funs nowadays. I thought using a fun was the (conceptually) cleanest way of passing the continuation, but plain_fsm also supports passing the name of the function (which then has to be exported.) You can force functions to be exported in a parse_transform. It doesn't make the code that much uglier than it already is. But I dislike handing the programmer surprises like automatically exporting a user-provided function. I think the programmer should do it, if it needs to be done. > I could see it being a compile error > if the user did something like: > > recieve > 'SYSTEM' -> do_foo(), idle(S); > ... > end > > In other words, the block executed when 'SYSTEM' is received should > be a single expr, and only a local function call... Actually, if you take the expressions given in that particular receive clause and wrap them inside a fun, you have your continuation. Then, it doesn't matter if there's more than one expression. There's still the question of which construct is the least bewildering to the user... (: > >> idle(S) -> >> extended_receive >> ... >> end. >> >> (One could also imagine a directive to replace the parser..., >> and why not the linter too, while we're at it. ;) > > What is this, Perl? :-) I think this sort of muddies the language > some, especially what if two different types of extended_receive were > to be used at once? What if I need to be a plain_fsm and want to also > have automatic handling of data received from gen_tcp by an active > socket? With parse transforms like I'm suggesting above, this is > easily possible, both plain_fsm and gen_tcp could inline their clauses > right into the same receive statement. But a single extended_receive > would be difficult otherwise. I don't see the difference, really. You're still doing a parse_transform, and even with the (receive 'SYSTEM' -> ... end) construct, you have to trust that the parse_transform does what you think it does. The only real difference is how you signal the customized semantics. I think it's a lot clearer to use a unique keyword which cannot be mistaken for valid Erlang with already given semantics. The only thing to worry about in the case of using a keyword is that it eventually become part of the Erlang language but then meaning something else. Solution - use a keyword that couldn't possibly become standard: idle(S) -> plain_fsm_receive ... end. or, since we're transforming tokens anyway, why not invent something entirely different -- a user-provided keyword syntax: idle(S) -> |plain_fsm::receive| ... end. This would even make it easier to transform the token stream, since we're not using an atom (which could occur anywhere), but using a sequence of tokens that at least I have never come across in an Erlang module before. The way I'd do it is to replace the token sequence with tokens representing valid erlang code, and then triggering a parse transform, almost exactly like in plain_fsm today. (It would also mess up Emacs indentation, of course... bummer.) /Uffe -- Ulf Wiger From ulf.wiger@REDACTED Thu Feb 12 09:40:28 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 12 Feb 2004 09:40:28 +0100 Subject: Lexing and parsing, was Re: plain_fsm - for beginners and purists In-Reply-To: <20040211183646.15162.qmail@web41901.mail.yahoo.com> References: <20040211183646.15162.qmail@web41901.mail.yahoo.com> Message-ID: On Wed, 11 Feb 2004 10:36:46 -0800 (PST), Thomas Lindgren wrote: > Interesting idea, but wouldn't the Module have to be > an entire tokenizer? Just processing a stream of > tokens (e.g., [... bang, bang, ...] => [..., bangbang, > ...]) might lead to confusion: how to separate "!!" > from "! !"? One easy way to address this would be to have the tokenizer also account for columns - not just line numbers. tok_xform([{'!', {L,Col}}, {'!',{L,Col1}}|T]) when Col1==Col+1 -> ... % bangbang; It would be _almost_ backward compatible. (: /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Thu Feb 12 15:47:12 2004 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 12 Feb 2004 09:47:12 -0500 Subject: plain_fsm - for beginners and purists In-Reply-To: References: <20040211051110.GA8922@spearce.org> <20040212004049.GA10867@spearce.org> Message-ID: <20040212144712.GA13365@spearce.org> Ulf Wiger wrote: > One interesting twist of the above is that it will actually > _appear_ to work, even if you forget to do the parse_transform - > it just doesn't handle system messages like you thought it > would. The wrapper function used in plain_fsm will actually > exit if you ever call it directly. So if you forget to do > the parse_transform, your program will exit immediately > with a reasonably descriptive exit reason. Yea, I noticed that. Nice touch. The more that I think about what you've said during this thread, the more I realize you may very well have gone with the overall best approach. The syntax is horrible with regards to what it actually means, but it may yeild the least surprises in every regard. It would be nice if the code just didn't compile if you forgot the parse transform, rather than waiting until runtime to crash however. :) > Actually, very few code changes break funs nowadays. > I thought using a fun was the (conceptually) cleanest way > of passing the continuation, but plain_fsm also supports > passing the name of the function (which then has to be > exported.) I thought a fun wasn't usable after a module was reloaded, because the reference to the code that the fun was using was directly to the a single version of the module (and not an external call)? Besides, can't a fun's magic name change between compiles, especially if I add another fun, so if it did use an external call to execute the fun in the new module, it might run the wrong fun? > or, since we're transforming tokens anyway, why not invent something > entirely different -- a user-provided keyword syntax: > > idle(S) -> > |plain_fsm::receive| > ... > end. This is interesting. New keywords will mess with nearly any indent code that actually reads and relies on the keywords. :) But with the above, you could actually have an indent program understand what was meant: | (start user kewyord) plain_fsm (name of module that will supply the parse transform) :: (split between module and original keyword) receive (native erlang keyword most like this new keyword) | (end user keyword) If this is the road taken, I'd like to ask that we make sure its stackable: plain_fsm_receive my_app_receive .... end. Or: -keyword(plain_fsm_receive, my_app_receive). plain_fsm_receive ... end. with the parse transform converting to my_app_receive, (rather than just receive) so another parse transform can kick in. This is already possible with your current design, so perhaps that's really the best we have today... -- Shawn. From ulf.wiger@REDACTED Thu Feb 12 16:30:20 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 12 Feb 2004 16:30:20 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: <20040212144712.GA13365@spearce.org> References: <20040211051110.GA8922@spearce.org> <20040212004049.GA10867@spearce.org> <20040212144712.GA13365@spearce.org> Message-ID: On Thu, 12 Feb 2004 09:47:12 -0500, Shawn Pearce wrote: > It would be nice if the code just didn't compile if you forgot the parse > transform, rather than waiting until runtime to crash however. :) I'm not sure this can be done... actually it could, if I made it a local function instead: idle(S) -> plain_fsm_receive( ... end). Then we have to hope that the programmer hasn't actually written a function plain_fsm_receive/1 for some other purpose... ;-) We can minimize the risk by inventing an unbelievably ugly name for the function... Everyone with a strong opinion on the subject, please speak up. > I thought a fun wasn't usable after a module was reloaded, because the > reference to the code that the fun was using was directly to the > a single version of the module (and not an external call)? > > Besides, can't a fun's magic name change between compiles, especially > if I add another fun, so if it did use an external call to execute the > fun in the new module, it might run the wrong fun? I can't account for the algorithm used to generate fun names, but it is relative to the enclosing function, so the only time you will break a fun during code change is if you've inserted a fun definition ahead of it in the same enclosing function... I think. > Or: > > -keyword(plain_fsm_receive, my_app_receive). > > plain_fsm_receive > ... > end. > > with the parse transform converting to my_app_receive, (rather than > just receive) so another parse transform can kick in. This is already > possible with your current design, so perhaps that's really the best > we have today... Ok, then let's add behaviour_info(keywords) -> [plain_fsm_receive]. And have the linter check that you're not redefining keywords used by the behaviour you're using. (: /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From kent@REDACTED Thu Feb 12 22:05:41 2004 From: kent@REDACTED (Kent Boortz) Date: 12 Feb 2004 22:05:41 +0100 Subject: Problems with erl_interface/ei in R9C? Message-ID: We separated the header files for the 'erl_interface' and 'ei' API from the header files internal to erl_interface/ei in R9C. The main base for this separation was the manual, i.e. the documented include files, functions and symbols was considered the API. For different reasons (for example missing documentation and the use of undocumented functions in code examples) header files, functions and symbols not documented seem to be in use making erl_interface/ei in R9C incompatible with earlier versions for some users. If you have problems upgrading from using erl_interface/ei in R9B or earlier to R9C because of this, please let me know and we will try to solve these problems in R9C-1. All *known* bugs in erl_interface/ei are solved (except the bad documentation and rpc not responding to ticks). If you know about a bug in R9C erl_interface/ei not listed below, please let me know, kent The erl_interface/ei convenience functions *_gethostby* are now documented and added to "erl_interface.h" and "ei.h". The following are reintroduced and are actually wrappers for the corresponding functions in 'ei' erl_gethostbyname() erl_gethostbyname_r() erl_gethostbyaddr() erl_gethostbyname_r() Some "ei_x" variants missing for the encoding functions were added ei_x_encode_boolean() ei_x_encode_char() ei_x_encode_port() ei_x_encode_ref() ei_x_encode_trace() A bug in ei_connect_init() was corrected where it may incorrectly result in a long node name (bug introduced in R9C). The special "res_gethostbyname()" code enabled if the ERL_RESOLV environment variable was set has been removed. Now all integer decoding functions can handle correct but unexpected encodings according to the external format specification (the emulator or erl_inteface will never create them). There where a potential problem on Solaris if the Solaris linker was used. Even if no "long long" functions were used in the user code the linkage could break because of the dependency for some "long long" operations to "libgcc.a", an gcc internal library. A bignum bug in erl_compare_ext() has been corrected. Several bugs in the "long long" encode and decode functions where corrected (test cases added and the functions now actually work). Now ei_decode_ulong() returns -1 when decoding 28 bit negative numbers. ei_encode_atom() is documented to truncate the name to MAXATOMLEN (256) characters. It now does. ei_encode_string() will now encode the empty string the same compact way the emulator does, as the empty list/nil []. ei_encode_string() now terminates the list created for strings > 65535 characters, i.e. adds the ending [] to the list. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From bfulg@REDACTED Fri Feb 13 00:25:11 2004 From: bfulg@REDACTED (Brent Fulgham) Date: Thu, 12 Feb 2004 15:25:11 -0800 (PST) Subject: Number Formatting Question Message-ID: <20040212232511.97689.qmail@web80101.mail.yahoo.com> I'm a newcoming to Erlang, so please bear with me. Is there any way to instruct Erlang to format a number with leading zeros? For example, I wanted to produce a standard hexadecimal dump of some IPTrace data. I figured out how to format the correct spacing (see the following pathetic Erlang hack): % Routine to pretty-print datagrams print_raw_bytes([], Count) -> io:format("~n"); print_raw_bytes([H|Tail], Count) -> io:format("~2.16B", [H]), Z= Count rem 2, IncCount = case Count of 1 -> Count + 1; 8 -> io:format(" "), Count + 1; 16 -> io:format("~n"), 1; _ -> if Z == 0 This produces the desired output as follows: RAW SEND DATA: 0 C 0 0 0 1 015 6D74 735F 696E 7172 0 B 230 3030 3031 3233 3535 0 RAW RECEIVED PACKET: 0 B 0 0 0 1 01A 0 0 016 035 3230 32 0 0 0 0 0 0 0 0 2 0 0 1387 0 0 0 0 What I am trying to achieve is: RAW SEND DATA: 000C 0000 0001 0015 6D74 735F 696E 7172 000B 0230 3030 3031 3233 3535 00 RAW RECEIVED PACKET: 000B 0000 0001 001A 0000 0016 0035 3230 3200 0000 0000 0000 0002 0000 1387 0000 0000 Any ideas? Thanks, -Brent From bengt.kleberg@REDACTED Wed Feb 11 08:43:01 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg (AL/EAB)) Date: Wed, 11 Feb 2004 08:43:01 +0100 Subject: unable to compiling on R9C In-Reply-To: References: Message-ID: <4029DD05.9000809@ericsson.com> Robert Balogh wrote: > Hej, > > I have got a big-big problam...So I have a module what I can not to > compile under R9C. If I go back to an older one erlang release I can. > Unfortunatelly there is no error, nothing hapening whan a start the > compilation. have you checked if the last line of the module has a new-line character? try adding one if it is missing, and then compile again. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Fri Feb 13 06:56:10 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 13 Feb 2004 00:56:10 -0500 Subject: List comprehension or lists:foldl/3 ? Message-ID: <20040213055610.GA14978@spearce.org> Which is the more preferred form amongst you hacker types? NodeList = [...], [erlang:monitor(process, {myserv, N}) || N <- NodeList], ok or NodeList = [...], lists:foldl( fun(N, _) -> erlang:monitor(process, {myserv, N}) end, 0, NodeList ), ok I'm not concerned about the speed here, as its a startup routine run once when the node boots. Even for a very large cluster of over 200+ nodes (highly unlikely in my application) this would take no time either way. This is a preferred syntax poll. I find the LC easier to read by far. -- Shawn. "... all the modern inconveniences ..." -- Mark Twain From cpressey@REDACTED Fri Feb 13 07:31:46 2004 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 12 Feb 2004 22:31:46 -0800 Subject: List comprehension or lists:foldl/3 ? In-Reply-To: <20040213055610.GA14978@spearce.org> References: <20040213055610.GA14978@spearce.org> Message-ID: <20040212223146.5735de6f.cpressey@catseye.mine.nu> On Fri, 13 Feb 2004 00:56:10 -0500 Shawn Pearce wrote: > Which is the more preferred form amongst you hacker types? > > NodeList = [...], > [erlang:monitor(process, {myserv, N}) || N <- NodeList], > ok > > or > > NodeList = [...], > lists:foldl( > fun(N, _) -> erlang:monitor(process, {myserv, N}) end, > 0, > NodeList > ), > ok > > I'm not concerned about the speed here, as its a startup routine > run once when the node boots. Even for a very large cluster of > over 200+ nodes (highly unlikely in my application) this would take > no time either way. This is a preferred syntax poll. > > I find the LC easier to read by far. > > -- > Shawn. I would probably use lists:foreach/2 instead just to drive home the fact that you're evaluating this for its side effects & don't care about the return value. But that's just me. -Chris From thomas.arts@REDACTED Fri Feb 13 08:29:48 2004 From: thomas.arts@REDACTED (Thomas Arts) Date: Fri, 13 Feb 2004 08:29:48 +0100 Subject: List comprehension or lists:foldl/3 ? References: <20040213055610.GA14978@spearce.org> <20040212223146.5735de6f.cpressey@catseye.mine.nu> Message-ID: <002801c3f203$2d82db00$6500a8c0@ituniv398> Hi Shawn I was just going to write basically the same as Christ wrote. You are not interested in the result of the monitor calls. Hence, why would you construct a list in memory, that is garbage directly after the call? >From your question I also deduced that you see foldl and list-comprehension as similar concepts. However, a list-comprehension is more comparable to a map or better a map with a filter application. Fold over a list could well result in something completely different than a list (e.g. a number). The lists:foreach/2 function is like a map when you are only interested in the side-effects. I prefer that one in this case. /Thomas --- Dr Thomas Arts Program Manager Software Engineering and Management IT-university in Gothenburg Box 8718, 402 75 Gothenburg, Sweden http://www.ituniv.se/ Tel +46 31 772 6031 Fax +46 31 772 4899 ----- Original Message ----- From: "Chris Pressey" To: "Shawn Pearce" Cc: Sent: Friday, February 13, 2004 7:31 AM Subject: Re: List comprehension or lists:foldl/3 ? > On Fri, 13 Feb 2004 00:56:10 -0500 > Shawn Pearce wrote: > > > Which is the more preferred form amongst you hacker types? > > > > NodeList = [...], > > [erlang:monitor(process, {myserv, N}) || N <- NodeList], > > ok > > > > or > > > > NodeList = [...], > > lists:foldl( > > fun(N, _) -> erlang:monitor(process, {myserv, N}) end, > > 0, > > NodeList > > ), > > ok > > > > I'm not concerned about the speed here, as its a startup routine > > run once when the node boots. Even for a very large cluster of > > over 200+ nodes (highly unlikely in my application) this would take > > no time either way. This is a preferred syntax poll. > > > > I find the LC easier to read by far. > > > > -- > > Shawn. > > I would probably use lists:foreach/2 instead just to drive home the fact > that you're evaluating this for its side effects & don't care about the > return value. But that's just me. > > -Chris > From vlad_dumitrescu@REDACTED Fri Feb 13 08:29:58 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 13 Feb 2004 08:29:58 +0100 Subject: plain_fsm - for beginners and purists References: Message-ID: Hi Ulf and Shawn, Are you going to start the revolution without me!? :-D *** I like the plain_fsm idea. However, I'm not very happy with either the parse transform or the other solutions. My first instinct was to use a macro, as Shawn suggested, but got a more than good explanation of why it doesn't work. There is one more alternative that wasn't discussed yet: receive .... %% nomal caluses Msg -> plain_fsm:handle(State, Msg) end; This is all plain Erlang, and nobody can misunderstand it. One possible problem is that we can't have this handling before all other processing, but it doesn't feels like a big constraint. Are there other reasons, Ulf? ;-) *** About the advances in scanning and parsing technology, I'd like to argue that they effectively create a new language. This is not wrong per se, but I'm not sure if it should be called Erlang then. The idea is very appealing, and I suppose there are already such languages being researched. If such degree of freedom is wanted, why not go to the roots and use Lisp? One can build almost any syntax on top of it, and for semantic changes the macros are already there. ;-) *** Since you also mentioned the !! operator, I have some problems with it (as it is defined now). While the idea is good, I feel that if it's going to be part of the language, the behaviour should not be user-defined. If one will be able to define an own rpc function to be used by !!, it's not going to be clear what the code does without knowledge of it. Another problem is that I feel that I'd like to be able to set a timeout for a rpc call. In this respect, an operator is less flexible than the corresponding function call. *** Just my 2 cents. best regards, Vlad From D.WILLIAMS@REDACTED Fri Feb 13 09:39:41 2004 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Fri, 13 Feb 2004 09:39:41 +0100 Subject: List comprehension or lists:foldl/3 ? Message-ID: > I was just going to write basically the same as Christ wrote. ^^^^^^ Well of course if you're going to invoke Him... > The lists:foreach/2 function is like a map when you > are only interested in the side-effects. I prefer that > one in this case. Me too. In general, I love list comprehensions, but to make my intent clear, I only use them when I am interested in the resulting list. Comprehensions produce a list. foreach is for side effects (nothing produced). foldl is for producing something other than a list (or as well as a list...) Dominic Williams. From ulf.wiger@REDACTED Fri Feb 13 10:11:45 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Fri, 13 Feb 2004 10:11:45 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: References: Message-ID: On Fri, 13 Feb 2004 08:29:58 +0100, Vlad Dumitrescu wrote: > There is one more alternative that wasn't discussed yet: > > receive > .... %% nomal caluses > Msg -> > plain_fsm:handle(State, Msg) > end; > > This is all plain Erlang, and nobody can misunderstand it. One possible > problem is that we can't have this handling before all other processing, > but it doesn't feels like a big constraint. Are there other reasons, > Ulf? ;-) Well, it forces the programmer to accept that messages not recognized by the preceding clauses (which are not system messages) are summarily discarded. In some cases, this is indeed what one wants, and then I'd agree that it's a better solution. In other cases, it might well be a disaster (possibly... I'm not totally convinced that handling of system messages and discarding unexpected messages don't practically always go together.) I could include that as an alternative. It could complement the others. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From richardc@REDACTED Fri Feb 13 10:38:15 2004 From: richardc@REDACTED (Richard Carlsson) Date: Fri, 13 Feb 2004 10:38:15 +0100 (MET) Subject: Number Formatting Question In-Reply-To: <20040212232511.97689.qmail@web80101.mail.yahoo.com> References: <20040212232511.97689.qmail@web80101.mail.yahoo.com> Message-ID: On Thu, 12 Feb 2004, Brent Fulgham wrote: > Is there any way to instruct Erlang to format a number > with leading zeros? The general control sequence is `~F.P.PadC' (field width, precision and pad char). Just change the line io:format("~2.16B", [H]), to io:format("~2.16.0B", [H]), For example: 1> io:format("~4.16.0b~n", [42]). 002a ok /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From vlad_dumitrescu@REDACTED Fri Feb 13 10:57:31 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 13 Feb 2004 10:57:31 +0100 Subject: plain_fsm - for beginners and purists References: Message-ID: From: "Ulf Wiger" > > receive > > .... %% nomal clauses > > Msg -> > > plain_fsm:handle(State, Msg) > > end; > > Well, it forces the programmer to accept that messages not recognized by > the preceding clauses (which are not system messages) are summarily > discarded. Okay, what about receive .... %% nomal clauses Msg -> plain_fsm:handle(State, Msg, Fun_that_handles_non_system_messages) end; It's a little ugly, but maybe not too much. Introducing parse_transforms (and maybe lexer_transforms) on a more regular basis is a cool idea, and interesting stuff might come out of it - but it's no longer matching the title of the topic "for beginners and purists" ;-) /Vlad From ulf.wiger@REDACTED Fri Feb 13 11:19:53 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Fri, 13 Feb 2004 11:19:53 +0100 Subject: plain_fsm - for beginners and purists In-Reply-To: References: Message-ID: On Fri, 13 Feb 2004 10:57:31 +0100, Vlad Dumitrescu wrote: > Okay, what about > > receive > .... %% nomal clauses > Msg -> > plain_fsm:handle(State, Msg, > Fun_that_handles_non_system_messages) > end; > > It's a little ugly, but maybe not too much. Unfortunately this violates the selective receive semantics. You cannot do this without consuming the message, and you can't put it back where it was. Thus, you reorder the messages in the queue, and this can cause subtle bugs. If you don't recognize the message, you need to either throw it away or avoid touching it in the first place. > Introducing parse_transforms (and maybe lexer_transforms) on a more > regular basis is a cool idea, and interesting stuff might come out of it > - but it's no longer matching the title of the topic "for beginners and > purists" ;-) Mnemosyne already does it. So does the fun2ms module in stdlib. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From vlad_dumitrescu@REDACTED Fri Feb 13 12:04:24 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 13 Feb 2004 12:04:24 +0100 Subject: plain_fsm - for beginners and purists References: Message-ID: > > Okay, what about > > > > receive > > .... %% normal clauses > > Msg -> > > plain_fsm:handle(State, Msg, > > Fun_that_handles_non_system_messages) > > end; > > > > It's a little ugly, but maybe not too much. > > Unfortunately this violates the selective receive semantics. > You cannot do this without consuming the message, and you can't > put it back where it was. Thus, you reorder the messages in the queue, > and this can cause subtle bugs. If you don't recognize the message, > you need to either throw it away or avoid touching it in the first > place. Ah, I see what you mean. > Mnemosyne already does it. So does the fun2ms module in stdlib. Of course they do -- it's only not beginner's stuff. Nor purist's. Because parse transforms exist, the compiler already is an extensible one. (*) What I think would be needed to raise this above the level of "black magic voodoo" is to be able to express the transformations in source code-like form (which would be something like a macro) By that I mean that instead of fiddling with the parse tree, in many cases it would be easier to define the transform like for example macro when Cond '->' Actions end -> if Cond -> Actions; false -> ok; end. The compiler would compile this in two parse trees, match the first against the source being compiled, transform it in the other one (replacing the placeholders), and insert it. It's not as simple as in Lisp, but nearly :-) /Vlad (*) If we could add lexer_transforms, then we could in principle graft any other language to the Erlang VM! From ingela@REDACTED Fri Feb 13 12:57:31 2004 From: ingela@REDACTED (Ingela Anderton) Date: Fri, 13 Feb 2004 12:57:31 +0100 Subject: ODBC and OpenBSD (update) References: Message-ID: <16428.48043.138467.720563@gargle.gargle.HOWL> Edmund Dengler wrote: > (2b) Try to figure out how to get the ODBC stuff working. Had to modify > the makefile in .../otp_src_R9C-0/lib to include ODBC as there > seemed to be included only if this was a Solaris box. Note that > following the instructions in the manual did not seem to work > as the ODBC did not install as per the manual. > (2c) Recompile and install Erlang. > (2d) Try out sample. > erl > > application:start(odbc). > > {ok, Ref} = odbc:connect("DSN=MyDatabase", []). > (2e) Get problems ("port_program_executable_not_found"). Determine that > this is due to odbcserver not being compiled. Try out Makefile, > attempts to compile simply as: > cc odbcserver.c -o odbcserver > Missing many includes and libraries. Compile by hand using: > gcc \ > -I/opt/unixodbc/2.2.7/include \ > -I/opt/erlang/9c.0/lib/erlang/lib/erl_interface-3.4/include \ > -L/opt/unixodbc/2.2.7/lib \ > -L/opt/erlang/9c.0/lib/erlang/lib/erl_interface-3.4/lib \ > -DMULTITHREAD_UNIX \ > odbcserver.c \ > -lei -lerl_interface -lodbc \ > -pthread \ > -o odbcserver > Install into location: > mkdir -p /opt/erlang/9c.0/lib/erlang/lib/odbc-1.0.8/priv/bin > cp odbcserver /opt/erlang/9c.0/lib/erlang/lib/odbc-1.0.8/priv/ Well this is a little short coming of the odbc application. This is mainly because it has not had a high enough priority to be fixed, when there is no paying customer that request it. OTP only supports odbc for solaris and windows. We have tested it with oracle and sql-server. But there is no technical reason why it should not work on other platforms. We are planing to put in configure information in the future so that odbc can be built on all unix-like platforms in the same way as other applications. However there is a separate Makefile delivered in ...lib/odbc-/c_src to help compile the application. You may read about this in the odbc users guide! Edmund Dengler wrote: > I turned on core dumping, and indeed odbcserver was dumping core. I > fetched and compiled psqlODBC (version 7.3.2) and added this to the > unixODBC install. With this, I was able to connect to the database, as > long as I specified [{scrollable_cursors,off}]. My guess is that psqlODBC (version 7.3.2) is a driver that only supports version 2.X of the ODBC-standard and not 3.0 as the erlang odbc application is designed for. However as I pointed out earlier the only function used by the erlang odbc application that seems to be incompatible with 2.X seems to be the check of what level of support for scrollable cursors is available in the driver, and if you disable the use of scrollable cursor there is no need to perform this check. -- /Ingela Ericsson AB - OTP team This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From vlad_dumitrescu@REDACTED Fri Feb 13 14:59:24 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 13 Feb 2004 14:59:24 +0100 Subject: plain_fsm - for beginners and purists References: Message-ID: Now that I engaged in such a strongly discouraged activity as playing with parse transforms... :-) I've played with them a little, and I can't help but be bothered by the fact that mnemosyne query comprehensions are in fact more than just a parse transform -- the parser and linter know about query expressions... This makes parse transforms less useful, because the original code needs to be parseable. Perhaps this was the intention, but it kills the wild dreams I had for the last few hours ;-) regards, Vlad From nicolas.niclausse@REDACTED Fri Feb 13 15:34:30 2004 From: nicolas.niclausse@REDACTED (Nicolas Niclausse) Date: Fri, 13 Feb 2004 15:34:30 +0100 Subject: patch for get_memory_usage_linux on linux-2.6 Message-ID: <87isibjbex.fsf@schultze.ird.idealx.com> Hello, Since /proc/meminfo has changed in linux 2.6, the os_mon application do not work anymore. The following patch fix the parsing of /proc/meminfo on a linux 2.6 kernel Btw, the fonction gives the memory used on a linux system, but since linux is using all the available memory for caching (and buffering), the free memory reported by this function is meaningless. Maybe we should subtract the cache size to the MemUsed value ? -------------- next part -------------- A non-text attachment was scrubbed... Name: mem_linux-2.6.patch Type: text/x-patch Size: 1084 bytes Desc: patch URL: -------------- next part -------------- -- Nicolas NICLAUSSE IDEALX S.A.S. T?l:01 44 42 00 00 http://IDEALX.com/ From spearce@REDACTED Fri Feb 13 15:47:30 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 13 Feb 2004 09:47:30 -0500 Subject: List comprehension or lists:foldl/3 ? In-Reply-To: <20040212223146.5735de6f.cpressey@catseye.mine.nu> References: <20040213055610.GA14978@spearce.org> <20040212223146.5735de6f.cpressey@catseye.mine.nu> Message-ID: <20040213144730.GA16207@spearce.org> Doh! I need to study my lists module API a little bit more often. I totally forgot that lists:foreach/2 exists, if I had remembered it was there I would have used that as my second case, rather than lists:foldl/3. I think Chris makes the best argument, lists:foreach/2 drives home the "I don't care about return values, just the side effect". While an LC is short and sweet, it does leave one scratching their head and saying "what about the returned references? why isn't something done with them?". I'm going to go through my code now and replace all LCs where I don't care about return values with lists:foreach. It really makes my intentions a little bit more clear. Thanks for the comments, they were very much appreciated. Chris Pressey wrote: > On Fri, 13 Feb 2004 00:56:10 -0500 > Shawn Pearce wrote: > > > > NodeList = [...], > > [erlang:monitor(process, {myserv, N}) || N <- NodeList], > > ok > > > > or > > > > NodeList = [...], > > lists:foldl( > > fun(N, _) -> erlang:monitor(process, {myserv, N}) end, > > 0, > > NodeList > > ), > > ok > > I would probably use lists:foreach/2 instead just to drive home the fact > that you're evaluating this for its side effects & don't care about the > return value. But that's just me. -- Shawn. Son, someday a man is going to walk up to you with a deck of cards on which the seal is not yet broken. And he is going to offer to bet you that he can make the Ace of Spades jump out of the deck and squirt cider in your ears. But son, do not bet this man, for you will end up with a ear full of cider. -- Sky Masterson's Father From spearce@REDACTED Fri Feb 13 16:06:01 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 13 Feb 2004 10:06:01 -0500 Subject: plain_fsm - for beginners and purists In-Reply-To: References: Message-ID: <20040213150601.GB16207@spearce.org> This is exactly one idea I had thought about proposing, and I nearly put it into my fsm behavior's code the other day. The problem is exactly what Ulf points out, you are removing the selective receive functionality entirely. There's two cases: 1) in the current state, we want to pull all messages, and maybe give error reports to let the admins/developers know an unsupported message was just received. 2) in the current state, we only want to pull a few messages, and leave the rest in the queue. These may be messages we will react to once we leave this state. Good example is a lock manager, when it enters the "lock_held" state it won't want to consume any incoming lock_request messages, just leave them in the queue. Now mix into those the fact that you may want to consume and handle system messages when in either type of receive. It may be very important to handle the system messages in case 2, as you may be waiting for an unlock_request message to come in, but it never will, because the locking process has been suspended by the release handler (for a pending code change). Thus the lock manager never can process the system suspend or code change messages, and the upgrade will have to abort. I really have to wonder, is it so hard to just make the developer do something such as: plain_fsm.hrl: -import({plain_fsm, [ handle_system_message/2, handle_parent_exit/1, handle_unknown_message/1 ]). user_module.erl: -include("plain_fsm.hrl"). -export([code_change/3]). Parent = parent(), receive {system, From, Message} -> handle_system_message(From, Message); {'EXIT', Parent, Reason} -> handle_parent_exit(Reason); ... Any -> handle_unknown_message(Any) end. ?? I guess the big problem is the simple fact that the developer might forget to make one of the calls in a stable state, or mess up the pattern and pass faulty messages to plain_fsm. But what we are talking about here is the correct handling of OTP system messages. To most people, OTP is "erlang" anyway, if you are in Erlang, you should try to use OTP when you can, because its done a lot of the hard work for you. So in reality, the "system" should be able to automatically process system messages. I think its just as fundamental to the langauge as mnemosyne's query [...] end LC. So what about adding an option to the receive statement that isn't specific to plain_fsm, but is instead related to/owned by the sys and proc_lib modules? recieve system a -> a(S), b -> b(S) end. Unfortunately this most likely would need changes to the linter and early stages of the parse tree construction as its definately not valid Erlang. But the point I'm trying to make is, perhaps this should be! Ulf Wiger wrote: > On Fri, 13 Feb 2004 10:57:31 +0100, Vlad Dumitrescu > wrote: > > >Okay, what about > > > >receive > > .... %% nomal clauses > > Msg -> > > plain_fsm:handle(State, Msg, > >Fun_that_handles_non_system_messages) > >end; > > > >It's a little ugly, but maybe not too much. > > Unfortunately this violates the selective receive semantics. > You cannot do this without consuming the message, and you can't > put it back where it was. Thus, you reorder the messages in the queue, > and this can cause subtle bugs. If you don't recognize the message, > you need to either throw it away or avoid touching it in the first > place. -- Shawn. You probably wouldn't worry about what people think of you if you could know how seldom they do. -- Olin Miller. From hal@REDACTED Fri Feb 13 16:34:17 2004 From: hal@REDACTED (Hal Snyder) Date: Fri, 13 Feb 2004 09:34:17 -0600 Subject: Problems with erl_interface/ei in R9C? In-Reply-To: (Kent Boortz's message of "12 Feb 2004 22:05:41 +0100") References: Message-ID: <87bro3j8na.fsf@ghidra.vail> Kent Boortz writes: > We separated the header files for the 'erl_interface' and 'ei' API > from the header files internal to erl_interface/ei in R9C. The main > base for this separation was the manual, i.e. the documented include > files, functions and symbols was considered the API. > > For different reasons (for example missing documentation and the use > of undocumented functions in code examples) header files, functions > and symbols not documented seem to be in use making erl_interface/ei > in R9C incompatible with earlier versions for some users. > > If you have problems upgrading from using erl_interface/ei in R9B or > earlier to R9C because of this, please let me know and we will try to > solve these problems in R9C-1. > > All *known* bugs in erl_interface/ei are solved (except the bad > documentation and rpc not responding to ticks). If you know about > a bug in R9C erl_interface/ei not listed below, please let me know, Please (if not already done): 1. Remove both instances of self->num = fd; in ei_connect.c so it is possible to use process id for transaction id to avoid the 6 + 1 = 4 scenario presented at EUC. Anyone wishing to preserve the old behavior can still set the value in their own code before calling ei, although I haven't thought of a reason to do so. 2. Also fix the select statement in ei_connect.c. A patch against R9C-0 showing both suggestions is here http://www.drxyzzy.org/ei-only/ei_connect.c.patch Thanks. From gordon.guthrie@REDACTED Fri Feb 13 16:47:15 2004 From: gordon.guthrie@REDACTED (Gordon Guthrie, BTP, BT, SE) Date: Fri, 13 Feb 2004 15:47:15 -0000 Subject: A problem with records... Message-ID: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> I'm having a strange problem - which might be trivial stupidity on my part :-< I have defined a record as so: -record(sms_message_out, {phonenumber, message}). I try and create an instance of it with this line of code: write_sms_message(PhoneNo, Message) -> Message = #sms_message_out{phonenumber = PhoneNo, message = Message}, % Bombs out here! (...) and I get this message: ERROR erlang code crashed: File: appmod:0 Reason: {{badmatch,{sms_message_out,"234567","esdfgjmn"}}, [{smsout,write_sms_message,2}, {smsout,out,1}, {yaws_server,deliver_dyn_part,9}, {yaws_server,aloop,3}, {yaws_server,acceptor0,2}, {proc_lib,init_p,5}]} Req: {http_request,'POST',{abs_path,"/smsout/smsout_post"},{1,1}} I have looked at this til my head hurts and compared it to (successful) record creations elsewhere in my code and I can't see anything wrong - but I might just be bug blind... Gordon ______________________________________________________________________ Scottish Enterprise Network http://www.scottish-enterprise.com Address & Contact Numbers 150 Broomielaw 5 Atlantic Quay Glasgow G2 8LU. Tel: +44 (0)141 248 2700. Fax: +44 (0)141 221 3217 message is sent in confidence for the addressee only. It may contain legally privileged information. The contents are not to be disclosed to anyone other than the addressee. Unauthorised recipients are requested to preserve this confidentiality and to advise the sender immediately of any error in transmission. From bengt.kleberg@REDACTED Fri Feb 13 17:21:17 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Fri, 13 Feb 2004 17:21:17 +0100 Subject: A problem with records... In-Reply-To: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> References: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> Message-ID: <402CF97D.30605@ericsson.com> Gordon Guthrie, BTP, BT, SE wrote: >I'm having a strange problem - which might be trivial stupidity on my part >:-< > >I have defined a record as so: > >-record(sms_message_out, {phonenumber, message}). > >I try and create an instance of it with this line of code: > >write_sms_message(PhoneNo, Message) -> > Message = #sms_message_out{phonenumber = PhoneNo, message = Message}, >% Bombs out here! > (...) > >and I get this message: > >ERROR erlang code crashed: > File: appmod:0 >Reason: {{badmatch,{sms_message_out,"234567","esdfgjmn"}}, > > you are using ''Message'' twice. both as the value for the message field, and as the variable holding the record. erlang is single assignment. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From gerd@REDACTED Fri Feb 13 17:37:26 2004 From: gerd@REDACTED (Gerd Flaig) Date: Fri, 13 Feb 2004 17:37:26 +0100 Subject: A problem with records... In-Reply-To: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> (Gordon Guthrie's message of "Fri, 13 Feb 2004 15:47:15 -0000") References: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> Message-ID: "Gordon Guthrie, BTP, BT, SE" writes: > write_sms_message(PhoneNo, Message) -> > Message = #sms_message_out{phonenumber = PhoneNo, message = > Message}, Message is bound in the head. Matching the newly created record against it fails. In your example: You match "esdfgjmn" = {sms_message_out,"234567","esdfgjmn"} which is obviously a mismatch. Goodbyte, Gerd. > % Bombs out here! > (...) > > and I get this message: > > ERROR erlang code crashed: > File: appmod:0 > Reason: {{badmatch,{sms_message_out,"234567","esdfgjmn"}}, > [{smsout,write_sms_message,2}, > {smsout,out,1}, > {yaws_server,deliver_dyn_part,9}, > {yaws_server,aloop,3}, > {yaws_server,acceptor0,2}, > {proc_lib,init_p,5}]} > Req: {http_request,'POST',{abs_path,"/smsout/smsout_post"},{1,1}} -- Gerd Flaig Technik gerd@REDACTED Bei Schlund + Partner AG Brauerstra?e 48 D-76135 Karlsruhe Physics is like sex: sure, it may give some practical results, but that's not why we do it. -- Richard Feynman From ulf.wiger@REDACTED Fri Feb 13 17:38:42 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Fri, 13 Feb 2004 17:38:42 +0100 Subject: jungerl updates: plain_fsm and lines Message-ID: A few updates in Jungerl (http://jungerl.sourceforge.net) I updated plain_fsm to also include the receive ...; Msg -> plain_fsm:handle_msg(Msg, S, ...) end. I also added the 'lines' contrib to jungerl. One bugfix (insert_after(0,...), thanks Joe), and two improvements: - creating a large array (equiv to lists:duplicate/2 or erlang:make_record/2) is now very fast -- on my slow machine, creating a 100,000 element array takes 11 ms. Almost as fast as make_record/2 and much faster than lists:duplicate/2. - calling lines:convert_from_list(L) is also much faster than before /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From gordon.guthrie@REDACTED Fri Feb 13 18:12:19 2004 From: gordon.guthrie@REDACTED (Gordon Guthrie, BTP, BT, SE) Date: Fri, 13 Feb 2004 17:12:19 -0000 Subject: A problem with records... Message-ID: <23659D76043CD7119EF400805FBE61F201ACE046@SENMAIL> Thanks to everyone for pointing out my Code Blindness... I had stared at that for an hour and was completely unable to see the blindingly obvious... Whenever I'm learning a new language I always spend too much time worrying about what I don't know to remember what I know fine well... Gordon > -----Original Message----- > From: Gerd Flaig [mailto:gerd@REDACTED] > Sent: 13 February 2004 16:37 > To: Gordon Guthrie, BTP, BT, SE > Cc: erlang-questions@REDACTED > Subject: Re: A problem with records... > > > "Gordon Guthrie, BTP, BT, SE" writes: > > > write_sms_message(PhoneNo, Message) -> > > Message = #sms_message_out{phonenumber = PhoneNo, message = > > Message}, > > Message is bound in the head. Matching the newly created > record against it fails. In your example: You match > > "esdfgjmn" = {sms_message_out,"234567","esdfgjmn"} > > which is obviously a mismatch. > > Goodbyte, Gerd. > > > % Bombs out here! > > (...) > > > > and I get this message: > > > > ERROR erlang code crashed: > > File: appmod:0 > > Reason: {{badmatch,{sms_message_out,"234567","esdfgjmn"}}, > > [{smsout,write_sms_message,2}, > > {smsout,out,1}, > > {yaws_server,deliver_dyn_part,9}, > > {yaws_server,aloop,3}, > > {yaws_server,acceptor0,2}, > > {proc_lib,init_p,5}]} > > Req: {http_request,'POST',{abs_path,"/smsout/smsout_post"},{1,1}} > > -- > Gerd Flaig Technik gerd@REDACTED > Bei Schlund + Partner AG Brauerstra?e 48 D-76135 Karlsruhe > Physics is like sex: sure, it may give some practical > results, but that's not why we do it. -- Richard Feynman > ______________________________________________________________________ Scottish Enterprise Network http://www.scottish-enterprise.com Address & Contact Numbers 150 Broomielaw 5 Atlantic Quay Glasgow G2 8LU. Tel: +44 (0)141 248 2700. Fax: +44 (0)141 221 3217 message is sent in confidence for the addressee only. It may contain legally privileged information. The contents are not to be disclosed to anyone other than the addressee. Unauthorised recipients are requested to preserve this confidentiality and to advise the sender immediately of any error in transmission. From bfulg@REDACTED Fri Feb 13 18:34:04 2004 From: bfulg@REDACTED (Brent Fulgham) Date: Fri, 13 Feb 2004 09:34:04 -0800 (PST) Subject: Number Formatting Question In-Reply-To: Message-ID: <20040213173404.96571.qmail@web80104.mail.yahoo.com> --- Richard Carlsson wrote: > > Is there any way to instruct Erlang to format a > number > > with leading zeros? > > The general control sequence is `~F.P.PadC' (field > width, > precision and pad char). Just change the line This is perfect -- thanks very much. -Brent From vances@REDACTED Sat Feb 14 00:48:35 2004 From: vances@REDACTED (Vance Shipley) Date: Fri, 13 Feb 2004 18:48:35 -0500 Subject: ets:from_dets/2 doesn't act as documented Message-ID: <20040213234835.GA9716@frogman.motivity.ca> The documentation says: "Fills an already created ETS table with the objects in the already opened DETS table named DetsTab. The ETS table is emptied before the objects are inserted." However it doesn't clear the existing table at all: 1> dets:open_file(foo, []). {ok,foo} 2> 2> dets:insert(foo, [{X,random:uniform(1000)}||X<-lists:seq(1,10)]). ok 3> dets:info(foo, size). 10 4> ets:new(foo, [named_table]). foo 5> ets:insert(foo, [{X,random:uniform(1000)}||X<-lists:seq(1,20)]). true 6> ets:info(foo, size). 20 7> ets:from_dets(foo, foo). true 8> ets:info(foo, size). 20 The last line shows that the ets table size is still 20, the size of the initial insert, and not the size of the dets file which is 10. Inspecting the ets tables I see that after ets:from_dets/2 the first 10 objects have been replaced with the new values but the last ten objects are still there from the first ets:insert/2. -Vance From vances@REDACTED Sat Feb 14 19:11:32 2004 From: vances@REDACTED (Vance Shipley) Date: Sat, 14 Feb 2004 13:11:32 -0500 Subject: Erlang distribution through firewalls In-Reply-To: <20040115022314.GD1314@frogman.motivity.ca> References: <20040115022314.GD1314@frogman.motivity.ca> Message-ID: <20040214181132.GA14852@frogman.motivity.ca> I had asked the question of how to achieve distribution when only port 22 (SSH) is available between the two systems. When you have a target node running behind a firewall where you are only given incoming SSH access to it. Answering my own question to document the solution for others searching in the future the solution to the problem is PPP over SSH. You use the remote shell feature of SSH to run pppd at the target node and create a virtual direct connection between the two machines. pppd pty ssh otpuser@REDACTED 'pppd notty 192.168.0.1:192.168.0.2' Then change your /etc/hosts entry for the machine target to be 192.168.0.1. You must also configure /etc/ppp/options at both ends to add noauth. -Vance From vances@REDACTED Sat Feb 14 21:33:51 2004 From: vances@REDACTED (Vance Shipley) Date: Sat, 14 Feb 2004 15:33:51 -0500 Subject: Erlang distribution through firewalls In-Reply-To: <20040214181132.GA14852@frogman.motivity.ca> References: <20040115022314.GD1314@frogman.motivity.ca> <20040214181132.GA14852@frogman.motivity.ca> Message-ID: <20040214203351.GB14852@frogman.motivity.ca> } pppd pty ssh otpuser@REDACTED 'pppd notty 192.168.0.1:192.168.0.2' Oops! It's actually: pppd pty "ssh otpuser@REDACTED 'pppd notty 192.168.0.1:192.168.0.2'" From taj.khattra@REDACTED Sun Feb 15 00:53:51 2004 From: taj.khattra@REDACTED (Taj Khattra) Date: 14 Feb 2004 23:53:51 -0000 Subject: CSLab pubs Message-ID: <20040214235351.19549.qmail@infidel.telus.net> the 'CSLab publications' link on http://www.erlang.org/doc.html which points to http://www.ericsson.com/cslab/publications.shtml does not work anymore. perhaps it should be changed to http://cs-lab.org/papers.html instead. thanks -taj From spearce@REDACTED Sun Feb 15 01:29:32 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 14 Feb 2004 19:29:32 -0500 Subject: disk_log:accessible_logs also reports pg2:which_groups Message-ID: <20040215002932.GA21695@spearce.org> This is a minor, but strange bug. In R9C-0, disk_log:accessible_logs/0 reports all pg2 process groups as distributed disk logs. I found this out by looking at disk_log:accessible_logs, and seeing all of my pg2 groups in there as well... This could create a weird situation if someone actually tried to do post a disk_log event to one of my process groups. I realize that no code should do this, as nobody knows what my process groups are named, so the chances of this happening are exactly 0, but it does look strange to someone new who is trying to work with disk_log. Perhaps just a note in the documentation of disk_log indicating this is a known bug? It seems to stem from the fact that disk_log assumes all pg2 process groups are distributed disk_logs, as if nobody else uses pg2... -- Shawn. We are Pentium of Borg. Division is futile. You will be approximated. (seen in someone's .signature) From vances@REDACTED Sun Feb 15 07:02:51 2004 From: vances@REDACTED (Vance Shipley) Date: Sun, 15 Feb 2004 01:02:51 -0500 Subject: Table Visualizer under OS X Message-ID: <20040215060251.GA16053@frogman.motivity.ca> I have been trying out the tools under Apple's OS X (Panther) using the Tcl/Tk Aqua package(*). This is a native port of the Tcl/Tk system to Apple's window environment Aqua (i.e. no XWindows). Most things work, and look very good too. I couldn't get the Table Visualizer to work though. It kept crashing with: =ERROR REPORT==== 15-Feb-2004::00:48:25 === Error in process <0.44.0> with exit value: {function_clause,[{lists,nthtail,[-8,[[{259,<0.34.0>},{433,<0.34.0>},{539,<0.34.0>},{611,<0.34.0>},{683,<0.34.0>},{755,<0.34.0>},{827,<0.34.0>},{899,<0.34.0>},{971,<0.34.0>},{1043,<0.34.0>}],... Killing two birds with one stone I played with the debugger to test that application out while using it to track down the tv problem. I came up with this patch which solves the above crash on my system anyway. I can't be sure what the intention of the code was, whether this was an error or whether it is supposed to accomplish something. It does however work fine for me now on Panther. I was seeing a configure event arrive with width & heigth each '1'. This eventually caused list:nthtail/2 to be called with a '-8'. I did see a reference somewhere that on Windows you might get two configure events, one for width and one for height so it may have to do with this of incompatability. -Vance (*) http://www.maths.mq.edu.au/~steffen/tcltk/TclTkAqua/ *** lib/tv/src/tv_pw.erl Sun Feb 15 00:39:59 2004 --- lib/tv/src/tv_pw.erl.orig Sun Feb 15 00:41:15 2004 *************** *** 277,287 **** FinalWidth = ?COMM_FUNC_FILE:max(W, MinAllowedWidth), FinalHeight = ?COMM_FUNC_FILE:max(H, MinAllowedHeight), ?WIN_FUNC_FILE:resize_window(WindowId, FinalWidth, FinalHeight), MasterPid ! #pc_win_conf{sender = self(), width = FinalWidth, ! height = FinalHeight}, NewWinP = WinP#window_params{window_width = FinalWidth, window_height = FinalHeight }, ProcVars#process_variables{window_params = NewWinP}; --- 277,287 ---- FinalWidth = ?COMM_FUNC_FILE:max(W, MinAllowedWidth), FinalHeight = ?COMM_FUNC_FILE:max(H, MinAllowedHeight), ?WIN_FUNC_FILE:resize_window(WindowId, FinalWidth, FinalHeight), MasterPid ! #pc_win_conf{sender = self(), width = FinalWidth, ! height = H}, NewWinP = WinP#window_params{window_width = FinalWidth, window_height = FinalHeight }, ProcVars#process_variables{window_params = NewWinP}; From bjarne@REDACTED Sun Feb 15 11:50:26 2004 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Sun, 15 Feb 2004 11:50:26 +0100 Subject: CSLab pubs References: <20040214235351.19549.qmail@infidel.telus.net> Message-ID: <001501c3f3b1$86215c00$d10a69d4@segeltorp> Hello There are other references to the Computer Science Laboratory, for instance under http://www.erlang.org/about.html They should all be changed to http://www.cs-lab.org/ All Erlang related CSLab papers are also included in http://www.erlang.se/publications/ I fixed that before leaving Ericsson. Best regards Bjarne ----- Original Message ----- From: "Taj Khattra" To: Sent: Sunday, February 15, 2004 12:53 AM Subject: CSLab pubs > the 'CSLab publications' link on http://www.erlang.org/doc.html > which points to http://www.ericsson.com/cslab/publications.shtml > does not work anymore. > > perhaps it should be changed to http://cs-lab.org/papers.html > instead. > > thanks > > -taj From baloghrobi@REDACTED Sun Feb 15 22:26:59 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Sun, 15 Feb 2004 22:26:59 +0100 Subject: list from a string Message-ID: Hej, Is it possible to get the list form this string? This is the string: "[a,b,c]" and I'd like to get back this list [a,b,c] thank you for your help, regards, /Robi _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 From ulf.wiger@REDACTED Sun Feb 15 22:52:06 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Sun, 15 Feb 2004 22:52:06 +0100 Subject: list from a string In-Reply-To: References: Message-ID: Erlang (BEAM) emulator version 5.3 [threads:0] Eshell V5.3 (abort with ^G) 1> String = "[a,b,c]". "[a,b,c]" 2> {ok,Tokens,_Line} = erl_scan:string(String ++ "."). {ok,[{'[',1},{atom,1,a},{',',1},{atom,1,b},{',',1},{atom,1,c},{']',1},{dot,1}], 1} 3> erl_parse:parse_term(Tokens). {ok,[a,b,c]} 4> On Sun, 15 Feb 2004 22:26:59 +0100, Robert Balogh wrote: > Hej, > > Is it possible to get the list form this string? > This is the string: "[a,b,c]" > and I'd like to get back this list [a,b,c] > > thank you for your help, > regards, > /Robi > > _________________________________________________________________ > Protect your PC - get McAfee.com VirusScan Online > http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 > -- Ulf Wiger From rvg@REDACTED Mon Feb 16 06:51:12 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Mon, 16 Feb 2004 07:51:12 +0200 Subject: Ports under windows In-Reply-To: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> References: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> Message-ID: <2090F0A9-6044-11D8-8CE5-000A956D87EE@patternmatched.com> Hi All, Today has been one of total frustration. We are trying to get a driver working as a port under windows. If you compile the example driver in the Interoperability tutorial using GCC in cygwin, it works perfectly. If you compile it under win32, specifically using Borland C++ Builder it doesn't. The erlang side of things always receive data from the port, but the win32 flavour of the driver just gets stuck in read() [from stdin]. We have to make the driver work with another [Delphi based] program, so we cannot use GCC. [We have tried all the "open_port" variations, including use_stdin, nouse_stdin, stream, binary, {packet, X}, etc etc] Here http://support.microsoft.com/default.aspx?scid=kb;en-us;Q190351 microsoft gives an example of a stdio based program. If we try to get the client portion [child.c at the bottom] to read from the erlang data, it simply hangs in readfile. We've also built a delphi version of these programs, using various ways of getting to stdin [win32 readfile, assignfile(), etc] So, what does erlang do different from other win32 based stdio applications, that is different under cygwin? The only included port in erlang that I know of, is ODBC and that is compiled by gcc, so it doesn't help me much here. Anyone that got a Delphi/Borland C++ based port running in Erlang? What are the tricks? I would like to test with MS Visual C++, but don't currently have access to it. Regards, Rudolph van Graan -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From rvg@REDACTED Mon Feb 16 06:55:34 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Mon, 16 Feb 2004 07:55:34 +0200 Subject: Table Visualizer under OS X In-Reply-To: <20040215060251.GA16053@frogman.motivity.ca> References: <20040215060251.GA16053@frogman.motivity.ca> Message-ID: Hi Vance, I've compiled Erlang using the darwinports based process on Panther and so far everything (specifically table visualizer) works as advertised. It has been a (small) schlep to get darwinports running at first, but after the cvs checkout, it went smoothly. Erlang also compiled properly. This is my list of installed ports: wyemac:~ root# port installed The following ports are installed: apr-0.9.5 apr-util-0.9.5 db4-4.2.52 erlang-R9C-0 expat-1.95.7 gawk-3.1.3 joe-2.9.8-pre1 neon-0.24.4 openssl-0.9.7c subversion-0.37.0 tk-8.4.5 xemacs-21.5.16 Rudolph van Graan > > I have been trying out the tools under Apple's OS X > (Panther) using the Tcl/Tk Aqua package(*). This is a > native port of the Tcl/Tk system to Apple's window > environment Aqua (i.e. no XWindows). > > Most things work, and look very good too. I couldn't > get the Table Visualizer to work though. It kept > crashing with: > > =ERROR REPORT==== 15-Feb-2004::00:48:25 === > Error in process <0.44.0> with exit value: > {function_clause,[{lists,nthtail,[ > -8,[[{259,<0.34.0>},{433,<0.34.0>},{539,<0.34.0>},{611,<0.34.0>},{683,< > 0.34.0>},{755,<0.34.0>},{827,<0.34.0>},{899,<0.34.0>},{971,<0.34.0>},{1 > 043,<0.34.0>}],... > > > Killing two birds with one stone I played with the debugger > to test that application out while using it to track down > the tv problem. I came up with this patch which solves the > above crash on my system anyway. I can't be sure what the > intention of the code was, whether this was an error or > whether it is supposed to accomplish something. It does > however work fine for me now on Panther. I was seeing a > configure event arrive with width & heigth each '1'. This > eventually caused list:nthtail/2 to be called with a '-8'. > I did see a reference somewhere that on Windows you might > get two configure events, one for width and one for height > so it may have to do with this of incompatability. > > > -Vance > > > (*) http://www.maths.mq.edu.au/~steffen/tcltk/TclTkAqua/ > > > > *** lib/tv/src/tv_pw.erl Sun Feb 15 00:39:59 2004 > --- lib/tv/src/tv_pw.erl.orig Sun Feb 15 00:41:15 2004 > *************** > *** 277,287 **** > FinalWidth = ?COMM_FUNC_FILE:max(W, MinAllowedWidth), > FinalHeight = ?COMM_FUNC_FILE:max(H, MinAllowedHeight), > ?WIN_FUNC_FILE:resize_window(WindowId, FinalWidth, > FinalHeight), > MasterPid ! #pc_win_conf{sender = self(), > width = FinalWidth, > ! height = FinalHeight}, > NewWinP = WinP#window_params{window_width = FinalWidth, > window_height = FinalHeight > }, > ProcVars#process_variables{window_params = NewWinP}; > > --- 277,287 ---- > FinalWidth = ?COMM_FUNC_FILE:max(W, MinAllowedWidth), > FinalHeight = ?COMM_FUNC_FILE:max(H, MinAllowedHeight), > ?WIN_FUNC_FILE:resize_window(WindowId, FinalWidth, > FinalHeight), > MasterPid ! #pc_win_conf{sender = self(), > width = FinalWidth, > ! height = H}, > NewWinP = WinP#window_params{window_width = FinalWidth, > window_height = FinalHeight > }, > ProcVars#process_variables{window_params = NewWinP}; > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From vlad_dumitrescu@REDACTED Mon Feb 16 09:44:58 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 16 Feb 2004 09:44:58 +0100 Subject: Ports under windows References: <23659D76043CD7119EF400805FBE61F201ACE043@SENMAIL> <2090F0A9-6044-11D8-8CE5-000A956D87EE@patternmatched.com> Message-ID: From: "Rudolph van Graan" > Anyone that got a Delphi/Borland C++ based port running in Erlang? What > are the tricks? I would like to test with MS Visual C++, but don't > currently have access to it. Hi, I have written a couple of Delphi port programs, and I think the attached one is the most advanced one, and it works. Please ask if something is unclear - the code is not very commented. The way I solved it is with a separate thread that reads from stdin and sends the messages asynchronously to the main program. This can be done by registering a custom Windows message, or by polling mailboxes in the idle loop of the window. The important thing is to be careful not to do things inside the reader thread. regards, Vlad -------------- next part -------------- A non-text attachment was scrubbed... Name: ErlPort.pas Type: application/octet-stream Size: 7695 bytes Desc: not available URL: From baloghrobi@REDACTED Mon Feb 16 13:02:15 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Mon, 16 Feb 2004 13:02:15 +0100 Subject: list from a string Message-ID: Hej Ulf, Thank you for your help...:-) /Robi >From: Ulf Wiger >To: erlang-questions@REDACTED >Subject: Re: list from a string >Date: Sun, 15 Feb 2004 22:52:06 +0100 > > >Erlang (BEAM) emulator version 5.3 [threads:0] > >Eshell V5.3 (abort with ^G) >1> String = "[a,b,c]". >"[a,b,c]" >2> {ok,Tokens,_Line} = erl_scan:string(String ++ "."). >{ok,[{'[',1},{atom,1,a},{',',1},{atom,1,b},{',',1},{atom,1,c},{']',1},{dot,1}], > 1} >3> erl_parse:parse_term(Tokens). >{ok,[a,b,c]} >4> > >On Sun, 15 Feb 2004 22:26:59 +0100, Robert Balogh >wrote: > >>Hej, >> >>Is it possible to get the list form this string? >>This is the string: "[a,b,c]" >>and I'd like to get back this list [a,b,c] >> >>thank you for your help, >>regards, >>/Robi >> >>_________________________________________________________________ >>Protect your PC - get McAfee.com VirusScan Online >>http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 >> > > > >-- >Ulf Wiger > _________________________________________________________________ The new MSN 8: advanced junk mail protection and 2 months FREE* http://join.msn.com/?page=features/junkmail From jonathan@REDACTED Mon Feb 16 17:00:40 2004 From: jonathan@REDACTED (jonathan@REDACTED) Date: Mon, 16 Feb 2004 16:00:40 -0000 Subject: Advantages of a large number of threads cf other approaches? Message-ID: <4030E928.10491.D7A0EF@localhost> I was discussing Erlang with a colleague and little difficulty convincing him either that its CSP approach was superior to trying to manage a large number of threads using semaphores, or that Erlangs VM threads scale better than antive threads on the OS's we're familiar with. What I had a harder time doing was convincing him that using a large number of threads was a best solution for any of the major cases we discussed: * Internet servers - why not use asynchronous sockets running in a single thread? * Simulations - why use an object per thread rather than a "classic" OO approach? One answer is that CSP threads (at least in the first case) lead to a simpler design and that Erlang itself has a host of features that support highly reliable programs. But I'd appreciate suggestions regarding other benefits, especially those arising from CSP itself. - Jonathan From sam@REDACTED Mon Feb 16 18:17:32 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 16 Feb 2004 18:17:32 +0100 Subject: Advantages of a large number of threads cf other approaches? References: <4030E928.10491.D7A0EF@localhost> Message-ID: <87lln39c5v.fsf@beeblebrox.enst.fr> >>>>> "Jonathan" == jonathan writes: > * Internet servers - why not use asynchronous sockets running in a > single thread? Because you also need asynchronous file reading. If a file takes N ms to load, then you will be blocking all the incoming requests. You will end up implementing a scheduler by yourself, which is much more easily achieved by using Erlang processes. The situation is even worse if some of your requests need to access external resources such as a database. > * Simulations - why use an object per thread rather than a "classic" > OO approach? Same reason. Sam -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From serge@REDACTED Mon Feb 16 19:26:29 2004 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 16 Feb 2004 13:26:29 -0500 Subject: Pattern matching vs. ETS lookups Message-ID: <40310B55.9050106@hq.idt.net> Could anyone shed some light on which one of the two approaches is better (i.e. faster, more compact, more efficient) - function overloading & use of pattern matching or ets lookups? A binary protocol uses the following convention: <> {FunID_MSB, FunID_LSB} determine the FunctionID to be called, that accepts a Body/binary. The main question is if the number of functions is large (~ 65536), is it better to implement header/body parsing using hard-coded patterns: % Input types: <> f1(<<0, 1, Body/binary>>) -> ...; f1(<<0, 2, Body/binary>>) -> ...; ... f1(<<255, 255, Body/binary>>) -> ... . or to have an ETS table that would store tuples in the form: {FunctionID, BodyParsingFunction} where the ETS table (Table) would initially be populated with a function list, and later do: f(<>, Table) -> BodyParsingFunction = ets:lookup_element(Table, {FunID_MSB, FunID_LSB}, 2), BodyParsingFunction(Body). Thanks. Serge From joe@REDACTED Mon Feb 16 19:32:24 2004 From: joe@REDACTED (Joe Armstrong) Date: Mon, 16 Feb 2004 19:32:24 +0100 (CET) Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <4030E928.10491.D7A0EF@localhost> Message-ID: On Mon, 16 Feb 2004 jonathan@REDACTED wrote: > I was discussing Erlang with a colleague and little difficulty > convincing him either that its CSP approach was superior to trying to > manage a large number of threads using semaphores, or that Erlangs VM > threads scale better than antive threads on the OS's we're familiar > with. What I had a harder time doing was convincing him that using a > large number of threads was a best solution for any of the major > cases we discussed: > > * Internet servers - why not use asynchronous sockets running in a > single thread? > Because of errors. Think of the process as not only providing units of concurrency but also of providing error encapsulation boundaries. Erlang was designed for programming fault-tolerant systems - to do so we must make sure that faulty code running somewhere in the system does not crash good code - the process provides the error encapsulation boundaries. This is the single most important property that a process has. Pseudo concurrency can be achieved in a single sequential process by writing your own scheduler and appropriately interleaving the computations (this is not a practice to be recommended, unless you are writing the Erlang run-time kernel) - the point is that it *can* be done. But containing the errors *cannot* be done within a programming language - to do this you need external control over your resources. In an OS you contain some errors to processes using hardware that prevents one process from writing to the memory used by another process. In Erlang each process has its own virtual memory space - so processes cannot overwrite each other's data structures. Erlang is great for (say) web servers because we can implement (say) the equivalent of CGI scripts as Erlang processes. In a regular web server environment a C program would never dare to run a CGI script in the same memory space as the web server - or even dare to run an arbitrary C program in the same memory space as the server because an error in the script could crash the entire server. So web servers always spawn off OS processes to evaluate scripts in - and this is *very* inefficient. In Erlang there is no such problem - processes are very light-weight and if they crash no harm is done. Interestingly Erlang and Apache perform equally when both are unloaded - this is hardly surprising since the heavy stuff in the Erlang I/O routines is all written in C and the programs are "BIF bound" - but under conditions of massive overload the story is very different. To see how things shape up under massive overload see: http://www.sics.se/~joe/apachevsyaws.html In this experiment Apache crashed when subject to a load of about 4000 parallel sessions - the Erlang web server (yaws) was happily ticking along at 80,000 parallel sessions. > * Simulations - why use an object per thread rather than a "classic" > OO approach? This depends upon the simulation - if you are modeling the real world then mapping each concurrent object in the real world with exactly one concurrent processes bridges between the gap between the model and the simulation code in a very natural way - the code will almost "write itself". The real world - is concurrent - there a loads of things going along in parallel in the real world - and yet most of our programming languages, which we use to model and interact with the real world are sequential - this makes the programs unnecessary complex and difficult to understand. /Joe > > One answer is that CSP threads (at least in the first case) lead to a > simpler design and that Erlang itself has a host of features that > support highly reliable programs. But I'd appreciate suggestions > regarding other benefits, especially those arising from CSP itself. > > - Jonathan > From ulf.wiger@REDACTED Mon Feb 16 20:23:09 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 16 Feb 2004 20:23:09 +0100 Subject: Pattern matching vs. ETS lookups In-Reply-To: <40310B55.9050106@hq.idt.net> References: <40310B55.9050106@hq.idt.net> Message-ID: On Mon, 16 Feb 2004 13:26:29 -0500, Serge Aleynikov wrote: > A binary protocol uses the following convention: > <> > > {FunID_MSB, FunID_LSB} determine the FunctionID to be called, that > accepts a Body/binary. > > The main question is if the number of functions is large (~ 65536), is > it better to implement header/body parsing using hard-coded patterns: Do you really have 65536 different body parsing functions? How are they identified in the first place? /Uffe -- Ulf Wiger From serge@REDACTED Mon Feb 16 21:04:11 2004 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 16 Feb 2004 15:04:11 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: References: <40310B55.9050106@hq.idt.net> Message-ID: <4031223B.60604@hq.idt.net> Well, the number 65536 is hypothetic. In reality it is around 3000 different functions (configuration, call control, signalling, etc.) of a hardware CSP switch (xl.com) that can be controlled through this binary protocol. The functions in the protocol are identified by a two byte number enumerated from {0,0} to {255,255}. Each function takes a binary containing it's specific parameters encoded in accordance with the protocol documentation. I'd like to see if it is possible to do an elegant & maintainable solution that would separate protocol encoding/decoding from the user application (perhaps by writing a behavior). Serge Ulf Wiger wrote: > On Mon, 16 Feb 2004 13:26:29 -0500, Serge Aleynikov > wrote: > >> A binary protocol uses the following convention: >> <> >> >> {FunID_MSB, FunID_LSB} determine the FunctionID to be called, that >> accepts a Body/binary. >> >> The main question is if the number of functions is large (~ 65536), is >> it better to implement header/body parsing using hard-coded patterns: > > > Do you really have 65536 different body parsing functions? > How are they identified in the first place? > > /Uffe From matthias@REDACTED Mon Feb 16 21:01:39 2004 From: matthias@REDACTED (Matthias Lang) Date: Mon, 16 Feb 2004 21:01:39 +0100 Subject: Pattern matching vs. ETS lookups In-Reply-To: <40310B55.9050106@hq.idt.net> References: <40310B55.9050106@hq.idt.net> Message-ID: <16433.8611.684778.787503@antilipe.corelatus.se> Serge Aleynikov writes: > Could anyone shed some light on which one of the two approaches is > better (i.e. faster, more compact, more efficient) - function > overloading & use of pattern matching or ets lookups? [...] > The main question is if the number of functions is large (~ 65536), is > it better to implement header/body parsing using hard-coded patterns: This is so far outside most people's experience that "try and see" is a reasonable way forward. Matthias From jonathan@REDACTED Mon Feb 16 22:06:59 2004 From: jonathan@REDACTED (jonathan@REDACTED) Date: Mon, 16 Feb 2004 21:06:59 -0000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: <4030E928.10491.D7A0EF@localhost> Message-ID: <403130F3.28869.5D234E@localhost> On 16 Feb 2004 at 19:32, Joe Armstrong wrote: > > * Internet servers - why not use asynchronous sockets running in a > > single thread? > > > > Because of errors. > > Think of the process as not only providing units of concurrency but > also of providing error encapsulation boundaries. > > Erlang was designed for programming fault-tolerant systems - to do > so we must make sure that faulty code running somewhere in the system > does not crash good code - the process provides the error > encapsulation boundaries. This is the single most important property > that a process has. This was pretty much what I very tentatively said. It's nice to have someone who's opinion eans something tell me I've not made a (tentative) idiot out of myself... > > * Simulations - why use an object per thread rather than a "classic" > > OO approach? > > This depends upon the simulation - if you are modeling the real > world then mapping each concurrent object in the real world with > exactly one concurrent processes bridges between the gap between the > model and the simulation code in a very natural way - the code will > almost "write itself". I've heard this said before (and have read code samples etc) but I keep feeling I'm missing something. It's so easy to have all your objects inherit from a Smalltalk/C++ base class with an update method and loop through all of them. Possibly I'm at the stage where I'm over-adapted to OO and no longer notice some of the discomforts... - Jonathan From jay@REDACTED Mon Feb 16 22:23:30 2004 From: jay@REDACTED (Jay Nelson) Date: Mon, 16 Feb 2004 13:23:30 -0800 Subject: Advantages of a large number of threads cf other approaches? Message-ID: <4.2.2.20040216131147.00d53ec0@duomark.com> There was a discussion of processes last year. I tried to catalog a variety of uses for them. See http://www.erlang.org/ml-archive/erlang-questions/200303/msg00441.html > It's so easy to have all your > objects inherit from a Smalltalk/C++ base class with an update > method and loop through all of them. This works fine if they are all in lock-step. If some are expected to react more quickly than others, you have to modify the loop. In the general case, your loop encodes priority and other semantics that are more rightfully imposed by the simulated objects rather than the simulation environment. If the "messages" or "update triggers" are unevenly distributed you have to deal with the problem without blocking progress of other individuals. If you want truly independent behavior and don't want to write an asynchronous handler rather than a looper, you are better off with an OS feature such as separate processes with a scheduler. Looping will be faster, but in general not simpler to code (although in the common case it will be familiar and straight-forward). Using processes allows a much simpler separation of concerns and the ability to scale to more processors at will (the real proof of whether the simulation is truly concurrent or if the simulated objects are independently modelled). For simple simulations you may never notice the difference between the two approaches. jay From vances@REDACTED Mon Feb 16 23:07:57 2004 From: vances@REDACTED (Vance Shipley) Date: Mon, 16 Feb 2004 17:07:57 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: <4031223B.60604@hq.idt.net> References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> Message-ID: <20040216220757.GA21424@frogman.motivity.ca> Serge, You don't necessarily need ETS either. I always resist using ETS when the data is not needed globally. If it's only needed by one process it should properly be kept within that 'cause it's nobody else's business. Put the mapping into a terms file: {0, {SomeAPIModule, SomeAPIFunction}}. {1, {SomeAPIModule, SomeOtherAPIFunction}. ... {3000, {SomeOtherAPIModule, YetAnotherAPIFunction}. In your startup function create a local state with the mappings. In your handler lookup up the module and function from the state data. Here are a couple ways to do it using a gen_server: Simple list: init(Path) -> file:consult(Path). %% conviently returns {ok, State} handle_info(<>, State) -> {M, F} = lists:keysearch(FunctionID, 2, State), M:F(Body). General balanced trees: init(Path) -> {ok, List} = file:consult(Path), {ok, gb_trees:from_ordict(List)}. handle_info(<>, State) -> {M, F} = gb_trees:get(FunctionID, State}, M:F(Body). I can't say which method is more effecient, hardcoded function clauses, or a lookup function however the above strikes me as more appropriate than ETS. -Vance From ulf.wiger@REDACTED Mon Feb 16 23:16:22 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 16 Feb 2004 23:16:22 +0100 Subject: Pattern matching vs. ETS lookups In-Reply-To: <40310B55.9050106@hq.idt.net> References: <40310B55.9050106@hq.idt.net> Message-ID: On Mon, 16 Feb 2004 13:26:29 -0500, Serge Aleynikov wrote: > The main question is if the number of functions is large (~ 65536), is > it better to implement header/body parsing using hard-coded patterns: > > % Input types: <> > f1(<<0, 1, Body/binary>>) -> ...; > f1(<<0, 2, Body/binary>>) -> ...; > ... > f1(<<255, 255, Body/binary>>) -> ... . I think this would set a new record for the Erlang compiler, the current record being held (I think) by the yecc-generated parser code for the SQL92 grammar. I think both yecc and the compiler were redesigned to handle that kind of module. The fun thing about yecc-generated code is that it's basically only two functions, but e.g. the megaco_text_parser.erl is ~22,000 lines of code. The compiler handles this quite nicely, so perhaps 65536 function clauses would be possible... nice thing about Erlang is that you can normally assume that there aren't many hard limits to worry about, but there may well be in this case (I have no idea). (: Try and see, and report the results. It's easy enough to generate a module of that size for a test. /Uffe -- Ulf Wiger From ulf.wiger@REDACTED Mon Feb 16 23:23:28 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 16 Feb 2004 23:23:28 +0100 Subject: Pattern matching vs. ETS lookups In-Reply-To: <20040216220757.GA21424@frogman.motivity.ca> References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> Message-ID: On Mon, 16 Feb 2004 17:07:57 -0500, Vance Shipley wrote: > In your handler lookup up the module and function > from the state data. Here are a couple ways to do it > using a gen_server: > > Simple list: > > init(Path) -> > file:consult(Path). %% conviently returns {ok, State} > > handle_info(<>, State) -> > {M, F} = lists:keysearch(FunctionID, 2, State), > M:F(Body). > > > General balanced trees: > > init(Path) -> > {ok, List} = file:consult(Path), > {ok, gb_trees:from_ordict(List)}. > > handle_info(<>, State) -> > {M, F} = gb_trees:get(FunctionID, State}, > M:F(Body). Or simply a tuple of tuples: f(<>, Matrix) -> BodyParsingFunction = element(FunID_LSB, element(FunID_MSB, Matrix)), BodyParsingFunction(Body). Hard to beat for speed, I think. /Uffe -- Ulf Wiger From vances@REDACTED Mon Feb 16 23:35:23 2004 From: vances@REDACTED (Vance Shipley) Date: Mon, 16 Feb 2004 17:35:23 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> Message-ID: <20040216223523.GD21424@frogman.motivity.ca> Very good however with this method you have to account for holes in the list. If the highest values of the 16 bit FunctionID are used you need the whole 65K in the tuple. This is pretty much what we used to do in the good old C days where this problem is solved by an array of pointers to functions. -Vance On Mon, Feb 16, 2004 at 11:23:28PM +0100, Ulf Wiger wrote: } } Or simply a tuple of tuples: } } f(<>, Matrix) -> } BodyParsingFunction = } element(FunID_LSB, element(FunID_MSB, Matrix)), } BodyParsingFunction(Body). } } Hard to beat for speed, I think. } } /Uffe } -- } Ulf Wiger From spearce@REDACTED Mon Feb 16 23:38:27 2004 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 16 Feb 2004 17:38:27 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <4030E928.10491.D7A0EF@localhost> References: <4030E928.10491.D7A0EF@localhost> Message-ID: <20040216223827.GA27585@spearce.org> I'm currently building a windows serial port driver for Erlang. (I'll post a link to the source to this list in a day or two.) Its a mess compared to native Erlang code. Because the serial ports on Windows are blocking, life gets ugly fast. But in Erlang a blocking operation would just cause you to spawn a new process and keep that blocking operation in its own seperate execution context. I'm basically rebuilding the erts event loop, just in an external port program. It really stinks. Erlang rules. :-) I totally agree with every comment everyone else has said on this topic, especially Joe's point about processes being able to crash and not affect others. OTP is really powerful in being able to monitor the crashes and take automatic corrective action. I have yet to see any other toolkit that does this as well as Erlang/OTP does. Even Java doesn't seem to offer the same stability, performance and ease of development, error trapping, and error recovery. I'm wodering how I can go back to my day job tomorrow after a week of vacation and several days of Erlang hacking. I write Java for a living. :-( jonathan@REDACTED wrote: > I was discussing Erlang with a colleague and little difficulty > convincing him either that its CSP approach was superior to trying to > manage a large number of threads using semaphores, or that Erlangs VM > threads scale better than antive threads on the OS's we're familiar > with. What I had a harder time doing was convincing him that using a > large number of threads was a best solution for any of the major > cases we discussed: > > * Internet servers - why not use asynchronous sockets running in a > single thread? > > * Simulations - why use an object per thread rather than a "classic" > OO approach? > > One answer is that CSP threads (at least in the first case) lead to a > simpler design and that Erlang itself has a host of features that > support highly reliable programs. But I'd appreciate suggestions > regarding other benefits, especially those arising from CSP itself. > > - Jonathan -- Shawn. The only function of economic forecasting is to make astrology look respectable. -- John Kenneth Galbraith From jonathan@REDACTED Tue Feb 17 01:19:14 2004 From: jonathan@REDACTED (jonathan@REDACTED) Date: Tue, 17 Feb 2004 00:19:14 -0000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <4.2.2.20040216131147.00d53ec0@duomark.com> Message-ID: <40315E02.3780.10D28DC@localhost> On 16 Feb 2004 at 13:23, Jay Nelson wrote: > There was a discussion of processes last year. I tried to > catalog a variety of uses for them. See > http://www.erlang.org/ml-archive/erlang-questions/200303/msg00441.html That's excellent. I'll go there now. > > It's so easy to have all your > > objects inherit from a Smalltalk/C++ base class with an update > > method and loop through all of them. > > This works fine if they are all in lock-step. If some are > expected to react more quickly than others, you have > to modify the loop. In the general case, your loop encodes > priority and other semantics that are more rightfully imposed > by the simulated objects rather than the simulation environment. I think most OO people would move this code out of the loop and either into the objects or a set of handles/iterators. > If you want truly independent behavior and don't want to write an > asynchronous handler Yes, the more the sim tends to be asynchronus the better off you are with threads. - Jonathan Coupe From taj.khattra@REDACTED Tue Feb 17 02:16:20 2004 From: taj.khattra@REDACTED (Taj Khattra) Date: Mon, 16 Feb 2004 17:16:20 -0800 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <40315E02.3780.10D28DC@localhost> References: <4.2.2.20040216131147.00d53ec0@duomark.com> <40315E02.3780.10D28DC@localhost> Message-ID: <20040217011620.GA4718@localhost.localdomain> On Tue, Feb 17, 2004 at 12:19:14AM -0000, jonathan@REDACTED wrote: > On 16 Feb 2004 at 13:23, Jay Nelson wrote: > > > There was a discussion of processes last year. I tried to > > catalog a variety of uses for them. See > > http://www.erlang.org/ml-archive/erlang-questions/200303/msg00441.html > > That's excellent. I'll go there now. also, don't forget about Joe's beautiful phd thesis: http://www.erlang.org/ml-archive/erlang-questions/200311/msg00141.html (i think it would be nice to have a link to Joe's thesis on the Erlang documentation page, since it explains the Erlang/OTP philosophy so well) -taj From ok@REDACTED Tue Feb 17 02:55:32 2004 From: ok@REDACTED (Richard A. O'Keefe) Date: Tue, 17 Feb 2004 14:55:32 +1300 (NZDT) Subject: Advantages of a large number of threads cf other approaches? Message-ID: <200402170155.i1H1tWCl145950@atlas.otago.ac.nz> > > * Simulations - why use an object per thread rather than a "classic" > > OO approach? > > This depends upon the simulation - if you are modeling the real > world then mapping each concurrent object in the real world with > exactly one concurrent processes bridges between the gap between the > model and the simulation code in a very natural way - the code will > almost "write itself". I've heard this said before (and have read code samples etc) but I keep feeling I'm missing something. It's so easy to have all your objects inherit from a Smalltalk/C++ base class with an update method and loop through all of them. No, it's not particularly easy. The two "classic" object-oriented programming languages that people tend to have heard of are Simula-67 and Smalltalk-72. Now Simula-67 was developed precisely to support object-oriented simulation. But Simula had TWO key features. OO was one, and (simulated) concurrency was the other. Simula simulations basically used co-operative multithreading. Bjarn Stroustrup, who invented C++, was familiar with Simula 67, and invented it in order to do the kind of simulations he was familiar with in a C-friendly/Algol-hostile milieu. Surprise surprise: the Cfront implementation of C++ from AT&T had TWO key features. OO was one, and (simulated) concurrency was the other (the Task Library, chapter 2 of the AT&T C++ library manual). Did I mention that Smalltalk-80 has TWO key features? OO is one, and (simulated) concurrency is the other. For what it's worth, there is a software development method called Jackson Structured Programming, developed years ago and used for serious EDP systems. One of the ideas in JSP is that you design your program as a collection of thousands of interacting concurrent processes/objects, and then "invert" the design to get your COBOL, because you obviously can't *really* have thousands of concurrent processes (:-). From andrae.muys@REDACTED Tue Feb 17 05:53:38 2004 From: andrae.muys@REDACTED (Andrae Muys) Date: Tue, 17 Feb 2004 14:53:38 +1000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <403130F3.28869.5D234E@localhost> References: <4030E928.10491.D7A0EF@localhost> <403130F3.28869.5D234E@localhost> Message-ID: <40319E52.6070200@braintree.com.au> jonathan@REDACTED wrote: > On 16 Feb 2004 at 19:32, Joe Armstrong wrote: > >>>* Internet servers - why not use asynchronous sockets running in a >>>single thread? >>> >> >> Because of errors. >> >> Think of the process as not only providing units of concurrency but >>also of providing error encapsulation boundaries. >> >> Erlang was designed for programming fault-tolerant systems - to do >>so we must make sure that faulty code running somewhere in the system >>does not crash good code - the process provides the error >>encapsulation boundaries. This is the single most important property >>that a process has. > > > This was pretty much what I very tentatively said. It's nice to have > someone who's opinion eans something tell me I've not made a > (tentative) idiot out of myself... > > >>>* Simulations - why use an object per thread rather than a "classic" >>>OO approach? >> >> This depends upon the simulation - if you are modeling the real >>world then mapping each concurrent object in the real world with >>exactly one concurrent processes bridges between the gap between the >>model and the simulation code in a very natural way - the code will >>almost "write itself". > > > I've heard this said before (and have read code samples etc) but I > keep feeling I'm missing something. It's so easy to have all your > objects inherit from a Smalltalk/C++ base class with an update method > and loop through all of them. Possibly I'm at the stage where I'm > over-adapted to OO and no longer notice some of the discomforts... > Hand-rolled co-operative multithreading. Been there, done that, no thanks. Yes this approach works *if* you can guarantee that every function called (directly or indirectly) from an update function is non-blocking. This also presumes you have access to co-routines in your language, or else everything becomes a state-machine whether you like it or not. So if you are programming in a language with reasonable support for co-routines; support for return-from-calling-coroutine semantics; and a non-blocking standard library (presumably using aformentioned semantics); then you are sitting pretty. If not then you will have to pay a rather high price for the dubious 'advantage' of not using a pleasant language like erlang ;). Andrae Muys -- Andrae Muys Engineer Braintree Communications "Now, allowing captured continuations to be inspected and altered at runtime (including binding mutation, complete rebinding of scopes, and call tree mutation)... *that* is really evil. And, I should point out, quite useful." - Dan Sugalski From vances@REDACTED Tue Feb 17 07:01:14 2004 From: vances@REDACTED (Vance Shipley) Date: Tue, 17 Feb 2004 01:01:14 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> Message-ID: <20040217060114.GE21424@frogman.motivity.ca> Curiosity got the better of me so I ran some benchmarks. The attached runs four different versions a gen_server. The first test is with a full 65K of {module, function} tuples of generated atoms. Each test is a loop of 1000 gen_server:call. CNT ACC OWN list 14605, 2874.423, 11382.772 gb_trees 14632, 163.546, 578.699 ets 14631, 148.579, 523.257 tuple of tuples 14632, 146.690, 512.442 This is the output of fprof:analyse. Obviously the list version is not effecient. The others seem equivalent. With only 3000 random entries: list 14647, 221.448, 814.819 gb_trees 14648, 154.442, 551.877 ets 14648, 155.908, 558.271 The list implentation isn't so bad now. There doesn't seem to be much difference in the others. I'm now satisfied that my gb_trees method is just as effecient as an ets table. -Vance From vances@REDACTED Tue Feb 17 07:13:38 2004 From: vances@REDACTED (Vance Shipley) Date: Tue, 17 Feb 2004 01:13:38 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: <20040217060114.GE21424@frogman.motivity.ca> References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> <20040217060114.GE21424@frogman.motivity.ca> Message-ID: <20040217061338.GF21424@frogman.motivity.ca> Forgot to attach the attachments ... On Tue, Feb 17, 2004 at 01:01:14AM -0500, Vance Shipley wrote: } } The attached runs four different versions a gen_server. -------------- next part -------------- -module(tets). -export([init/1, handle_call/3, terminate/2]). -behaviour(gen_server). init(Used) -> State = ets:new(mf, [private]), ets:insert(State, ttables:make_list(Used)), {ok, State}. handle_call(<>, _From, State) -> case catch ets:lookup_element(State, FunctionID, 2) of {'EXIT', _Reason} -> {reply, undefined, State}; {M, F} -> {reply, {M, F}, State} end. terminate(Reason, State) -> ok. -------------- next part -------------- -module(ttime). -export([tlist/2, tlist/1, ttree/2, ttree/1, ttuples/1, tets/2, tets/1]). tlist(N) -> tlist(N, 16#ffff). tlist(N, Used) -> go(N, Used, tlist). ttree(N) -> ttree(N, 16#ffff). ttree(N, Used) -> go(N, Used, ttree). ttuples(N) -> go(N, 16#ffff, ttuples). tets(N) -> tets(N, 16#ffff). tets(N, Used) -> go(N, Used, tets). go(N, Used, Module) -> {ok, Pid} = gen_server:start_link(Module, Used, []), TraceFile = atom_to_list(Module) ++ ".trace", ok = fprof:trace(start, TraceFile), do(Pid, N, []), fprof:trace(stop). do(Pid, 0, Acc) -> Acc; do(Pid, N, Acc) -> Bin = <<(random:uniform(16#ffff)):16, <<0:256>>/binary>>, MF = gen_server:call(Pid, Bin), do(Pid, N - 1, Acc ++ [MF]). -------------- next part -------------- -module(ttree). -export([init/1, handle_call/3, terminate/2]). -behaviour(gen_server). init(Used) -> {ok, ttables:make_tree(Used)}. handle_call(<>, _From, State) -> case gb_trees:lookup(FunctionID, State) of {value, {M, F}} -> {reply, {M, F}, State}; none -> {reply, undefined, State} end. terminate(Reason, State) -> ok. -------------- next part -------------- -module(ttables). -export([make_list/0, make_list/1, make_tree/0, make_tree/1, make_tuple_of_tuples/0]). make_list() -> make_list(16#ffff). make_list(Used) -> make_list(Used, 16#ffff, []). make_list(Used, -1, Acc) -> Acc; make_list(Used, X, Acc) -> case skip(Used) of false -> make_list(Used, X - 1, [{X, make_tuple()}] ++ Acc); true -> make_list(Used, X - 1, Acc) end. make_tree() -> make_tree(16#ffff). make_tree(Used) -> gb_trees:from_orddict(make_list(Used)). make_tuple_of_tuples() -> make_tuple_of_tuples(16#ff, []). make_tuple_of_tuples(-1, Acc) -> list_to_tuple(Acc); make_tuple_of_tuples(X, Acc) -> T = make_tuples(16#ff, []), make_tuple_of_tuples(X -1, [T] ++ Acc). make_tuples(-1, Acc) -> list_to_tuple(Acc); make_tuples(X, Acc) -> make_tuples(X -1, [make_tuple()] ++ Acc). make_tuple() -> {make_atom(), make_atom()}. make_atom() -> Length = random:uniform(20) + 5, make_atom(Length, []). make_atom(0, Acc) -> list_to_atom(Acc); make_atom(X, Acc) -> C = random:uniform(26) + 96, make_atom(X - 1, Acc ++ [C]). skip(Used) -> case random:uniform(round(16#ffff/Used)) of 1 -> false; _ -> true end. -------------- next part -------------- -module(tlist). -export([init/1, handle_call/3, terminate/2]). -behaviour(gen_server). init(Used) -> {ok, ttables:make_list(Used)}. handle_call(<>, _From, State) -> case lists:keysearch(FunctionID, 1, State) of {value, {M, F}} -> {reply, {M, F}, State}; false -> {reply, undefine, State} end. terminate(Reason, State) -> ok. -------------- next part -------------- -module(ttuples). -export([init/1, handle_call/3, terminate/2]). -behaviour(gen_server). init(_) -> {ok, ttables:make_tuple_of_tuples()}. handle_call(<>, _From, State) -> {M, F} = element(FunID_LSB + 1, element(FunID_MSB + 1, State)), {reply, {M, F}, State}; handle_call({stop, Reason}, _From, State) -> {stop, Reason, State}. terminate(Reason, State) -> ok. From vlad_dumitrescu@REDACTED Tue Feb 17 08:32:18 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 08:32:18 +0100 Subject: Advantages of a large number of threads cf other approaches? References: <4030E928.10491.D7A0EF@localhost> <20040216223827.GA27585@spearce.org> Message-ID: From: "Shawn Pearce" > I'm wodering how I can go back to my day job tomorrow after a week of > vacation and several days of Erlang hacking. I write Java for a > living. :-( Well, it's going to be difficult :-) I know, I am going through it myself. What keeps me going is thinking how simple it would be to rewrite the whole system in Erlang. I also thought about trying some heavy sedation, but since I am driving from and to home, it's not a good idea :-P regards, Vlad From vances@REDACTED Tue Feb 17 09:30:43 2004 From: vances@REDACTED (Vance Shipley) Date: Tue, 17 Feb 2004 03:30:43 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: <20040217060114.GE21424@frogman.motivity.ca> References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> <20040217060114.GE21424@frogman.motivity.ca> Message-ID: <20040217083043.GG21424@frogman.motivity.ca> } With only 3000 random entries: } } list 14647, 221.448, 814.819 } gb_trees 14648, 154.442, 551.877 } ets 14648, 155.908, 558.271 For completeness I made a function clause version of the server with 3000 clauses: clauses 14663, 324.492, 1143.447 I tried to make a clauses version of the 65K test however it's been compiling for over an hour now so I think we can conclude that that model isn't workable. One thing I noticed during this testing was that the gb_trees and tuples versions of State cause some problems with error logging. It seems that while lists are throttled and replaced with a tail of ... tuples are not. When there was a crash we got 65 thousand lines in the error report. In a way this is an advantage over the ets version as we have all the state data avilable in a crash to portmortem. We don't really want all that printed to stdio though. -Vancxe From baloghrobi@REDACTED Tue Feb 17 09:37:46 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Tue, 17 Feb 2004 09:37:46 +0100 Subject: highlight erlang editor for windows Message-ID: Hej, I'd like to ask you can I download somewhere a highlight erlang editor for windows? thanks for your help, regards, /Robi _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 From joe@REDACTED Tue Feb 17 10:10:31 2004 From: joe@REDACTED (Joe Armstrong) Date: Tue, 17 Feb 2004 10:10:31 +0100 (CET) Subject: Higher order receieve anybody Message-ID: I've just been reading the discussion "Re: plain_fsm - for beginners and purists" and read the following: > > Okay, what about > > > > receive > > .... %% normal clauses > > Msg -> > > plain_fsm:handle(State, Msg, > > Fun_that_handles_non_system_messages) > > end; > > > > It's a little ugly, but maybe not too much. > What Uffe and Vlad *really* need is a "higher order" receives ... The idea is to rewrite: receive {a, X} -> ... b -> Y -> ... end as F = fun({a,X}) -> ... (b) -> ... (Y) -> ... end, Z = receive F, If we introduce an infix ? operator, we'd get: Z = ?F Why is it not like this today? - Answer: a historical accident. To begin with we had only first order functions, both functions and receive patterns were first order. We talked for a long time about "higher order patterns" in receives without really understanding what this meant. The notion of a pattern is intimately connected to the notion of an action which must be performed when the pattern is matched - the *combination* of a pattern and an action is expressed in the fun notation. Fun = fun(Pattern1) -> Actions1; (Pattern2) -> Actions2; ... end. Now receive is first order - ie it only takes fixed patterns. We write receive Pattern1 -> Actions1; Pattern2 -> Actions2; ... end This is very near but not quite the syntax of a Fun - so why not be consistent and add higher order receive patterns, thus receive fun(Pattern1) -> Actions1; (Pattern2) -> Actions2; ... end. Then receive becomes higher order and we can write Fun = fun(Pattern1) -> Actions1; (Pattern2) -> Actions2 ... end receive Fun and Uffe's plain_fsm becomes a simple higher order function. /Joe So now all I'd like in Erlang is: 1) Higher order code 2) *Proper* structs 3) !! 4) Higher order receive 5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard C) From tony@REDACTED Tue Feb 17 10:37:35 2004 From: tony@REDACTED (Tony Rogvall) Date: Tue, 17 Feb 2004 10:37:35 +0100 Subject: Pattern matching vs. ETS lookups In-Reply-To: <20040217083043.GG21424@frogman.motivity.ca> Message-ID: On Tuesday, Feb 17, 2004, at 09:30 Europe/Stockholm, Vance Shipley wrote: > > > I tried to make a clauses version of the 65K test however > it's been compiling for over an hour now so I think we can > conclude that that model isn't workable. > I am also trying that, but like you said, it is STILL compiling????? What on earth is going on in the compiler??? The structure of the code is extremely simple it should be a matter of seconds to compile, basically read it and write it (someone :-) My version just looks like: ... handle_call(<>, _From, State) -> case FunctionID of 0 -> {reply,{lzajpvnqkvo,zaviohpnsfgewpcrzqzed},State}; 1 -> {reply,{pibpulozsusmmypocy,qfuwgkkvejzjlbtkdgebew},State}; 2 -> {reply,{aipvkpmsyjizeynqdpnnqpt,lhmtwwrawienmegfaamcsxd},State}; 3 -> {reply,{hqccfokzabnbtvyw,tshigwfuunhmnototydp},State}; 4 -> {reply,{vhcsnibefbubf,cqazgqwcgvrmyfggvk},State}; 5 -> {reply,{qcefxjnojnrake,evcfxizafalknzjkfhcbkjom},State}; 6 -> {reply,{liuvmdamtisxpqgdqoav,omqtrgaxealzjdllggegrw},State}; 7 -> {reply,{dgvhztimzjoc,xxszgkqxcuupw},State}; 8 -> {reply,{rvsywvgltmmmnnyt,hrazckuvs},State}; ... 65534 -> {reply,{blkkrhio,vaxzhrmipoxrvljrfrualfcw},State}; 65535 -> {reply,{lehgpela,hjjqvkdpuzj},State}; _ -> {reply, undefined, State} end. /Tony From ulf.wiger@REDACTED Tue Feb 17 10:42:30 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 17 Feb 2004 10:42:30 +0100 Subject: Higher order receieve anybody In-Reply-To: References: Message-ID: On Tue, 17 Feb 2004 10:10:31 +0100 (CET), Joe Armstrong wrote: > What Uffe and Vlad *really* need is a "higher order" receives ... > > The idea is to rewrite: > > receive > {a, X} -> ... > b -> > Y -> ... > end > > as > > F = fun({a,X}) -> ... > (b) -> ... > (Y) -> ... > end, > Z = receive F, > > > If we introduce an infix ? operator, we'd get: > > Z = ?F My first (*) version looked like this: idle(S) -> plain_fsm:recv( fun({a, x}) -> ...; (b) -> .... (Y) -> ... end). (*) in this iteration; I've attacked the problem a number of times over the past years. This happens to be quite similar to what you propose, except of course that you propose a language change, while my hack was just a way to trigger the parse_transform. I changed it to plain_fsm:extended_receive( receive ... end) because it was easier to introduce into legacy code. 3.5 years ago, I had the idea that one should be able to extend the receive semantics using some "system directive" (disregard the syntax): $extend_receive(system_receive) -> receive {system, From, Msg} -> sys:handle_system_messages(...); $receive() end. But with Joe's suggestion, no keyword redefinition or parse_transform is needed. (I also imagined the directives $inherit_api(FromModule) and $fast_path(Function, Arity) -> hard | {slow_path, fun()} (where 'hard' indicates EXIT if the fast-path code throws an exception; and {slow_path, F} means, exit and run F instead.)) /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From bjorn@REDACTED Tue Feb 17 10:42:48 2004 From: bjorn@REDACTED (=?ISO-8859-1?Q?Bj=F6rn_Bylander?=) Date: Tue, 17 Feb 2004 10:42:48 +0100 Subject: highlight erlang editor for windows In-Reply-To: References: Message-ID: <4031E218.6050705@loxysoft.se> Both Emacs and Vim do syntax highlighting for Erlang and are available for Windows. I'm sure there are others... /Bj?rn Robert Balogh wrote: > Hej, > > I'd like to ask you can I download somewhere a highlight erlang editor > for windows? > > thanks for your help, > > regards, > /Robi > From baloghrobi@REDACTED Tue Feb 17 11:27:07 2004 From: baloghrobi@REDACTED (Robert Balogh) Date: Tue, 17 Feb 2004 11:27:07 +0100 Subject: highlight erlang editor for windows Message-ID: Hi Bjorn, Thanks a lot... regards, /Robi >From: Bj?rn Bylander >To: erlang-questions@REDACTED >Subject: Re: highlight erlang editor for windows >Date: Tue, 17 Feb 2004 10:42:48 +0100 > > >Both Emacs and Vim do syntax highlighting for Erlang and are available for >Windows. I'm sure there are others... > >/Bj?rn > >Robert Balogh wrote: > >>Hej, >> >>I'd like to ask you can I download somewhere a highlight erlang editor for >>windows? >> >>thanks for your help, >> >>regards, >>/Robi >> > _________________________________________________________________ MSN 8 with e-mail virus protection service: 2 months FREE* http://join.msn.com/?page=features/virus From erlang@REDACTED Tue Feb 17 11:42:32 2004 From: erlang@REDACTED (Peter-Henry Mander) Date: Tue, 17 Feb 2004 10:42:32 +0000 Subject: highlight erlang editor for windows In-Reply-To: References: Message-ID: <20040217104232.2dc497ec.erlang@manderp.freeserve.co.uk> Hi Robi, There's SciTE from scintilla.org too, if you want a more Windows style text editor. It has syntax highlighting for Erlang, courtesy of yours truely :-) Pete. On Tue, 17 Feb 2004 09:37:46 +0100 "Robert Balogh" wrote: > Hej, > > I'd like to ask you can I download somewhere a highlight erlang editor for > windows? > > thanks for your help, > > regards, > /Robi > > _________________________________________________________________ > Protect your PC - get McAfee.com VirusScan Online > http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 > -- "The Tao of Programming flows far away and returns on the wind of morning." From joachim.durchholz@REDACTED Tue Feb 17 12:35:21 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Tue, 17 Feb 2004 12:35:21 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <200402170155.i1H1tWCl145950@atlas.otago.ac.nz> References: <200402170155.i1H1tWCl145950@atlas.otago.ac.nz> Message-ID: <4031FC79.7050207@web.de> Richard A. O'Keefe wrote: > Did I mention that Smalltalk-80 has TWO key features? OO is one, and > (simulated) concurrency is the other. That would be interesting news to me - where is the concurrency in Smalltalk-80? (Not in the message sends - these are synchronous. Took me some hours to figure that out, texts were quite handwavy about what exactly happens in a message send - I had to analyze the interpreter listing given in one of the books to be sure.) Regards, Jo -- Currently looking for a new job. From joachim.durchholz@REDACTED Tue Feb 17 12:36:45 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Tue, 17 Feb 2004 12:36:45 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: Message-ID: <4031FCCD.4090500@web.de> Joe Armstrong wrote: > Interestingly Erlang and Apache perform equally when both are > unloaded - this is hardly surprising since the heavy stuff in > the Erlang I/O routines is all written in C and the programs are > "BIF bound" - but under conditions of massive overload the story > is very different. > > To see how things shape up under massive overload see: > > http://www.sics.se/~joe/apachevsyaws.html > > In this experiment Apache crashed when subject to a load of about > 4000 parallel sessions - the Erlang web server (yaws) was > happily ticking along at 80,000 parallel sessions. That's interesting. Joe, would you or Ali be interested in running the same test with a Linux 2.6 kernel? They implemented an O(1) scheduler there, and it would help to determine whether Apache's crash is due to OS process issues or due to Apache. Regards, Jo -- Currently looking for a new job. From joe@REDACTED Tue Feb 17 12:51:17 2004 From: joe@REDACTED (Joe Armstrong) Date: Tue, 17 Feb 2004 12:51:17 +0100 (CET) Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <4031FCCD.4090500@web.de> Message-ID: On Tue, 17 Feb 2004, Joachim Durchholz wrote: > Joe Armstrong wrote: > > > Interestingly Erlang and Apache perform equally when both are > > unloaded - this is hardly surprising since the heavy stuff in > > the Erlang I/O routines is all written in C and the programs are > > "BIF bound" - but under conditions of massive overload the story > > is very different. > > > > To see how things shape up under massive overload see: > > > > http://www.sics.se/~joe/apachevsyaws.html > > > > In this experiment Apache crashed when subject to a load of about > > 4000 parallel sessions - the Erlang web server (yaws) was > > happily ticking along at 80,000 parallel sessions. > > That's interesting. > > Joe, would you or Ali be interested in running the same test with a > Linux 2.6 kernel? They implemented an O(1) scheduler there, and it would > help to determine whether Apache's crash is due to OS process issues or > due to Apache. Right now I don't have any time to re-do the tests. My guess is that the problem lies in the kernel. At 4000+ processes both Java and C++ started behaving in a wierd manner - I don't think this was a co-incidence. /Joe > > Regards, > Jo > -- > Currently looking for a new job. > From mickael.remond@REDACTED Tue Feb 17 13:24:40 2004 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 17 Feb 2004 13:24:40 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <4031FCCD.4090500@web.de> References: <4031FCCD.4090500@web.de> Message-ID: <20040217122439.GD3109@cgey.com> * Joachim Durchholz [2004-02-17 12:36:45 +0100]: > Joe, would you or Ali be interested in running the same test with a > Linux 2.6 kernel? They implemented an O(1) scheduler there, and it would > help to determine whether Apache's crash is due to OS process issues or > due to Apache. It seems that the kernel threading model in 2.6 improves scalability on high-end SMP machines: http://www-106.ibm.com/developerworks/linux/library/l-web26/?ca=dgr-lnxw94KernCompare Thread can be created more quickly. However, I do not know to which extend the 2.6 thread are lighter than 2.4. If the memory taken for each thread is still important, this is a direct and quickly reached limitation to the number of thread you can manage. You end up filling up the memory too quickly and soon start deterioating performance. Note Yaws should be tested with 2.6 either as some kernel improvments can also benefit to it. -- Micka?l R?mond http://www.erlang-projects.org/ From serge@REDACTED Tue Feb 17 13:37:56 2004 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 17 Feb 2004 07:37:56 -0500 Subject: Pattern matching vs. ETS lookups In-Reply-To: <20040217060114.GE21424@frogman.motivity.ca> References: <40310B55.9050106@hq.idt.net> <4031223B.60604@hq.idt.net> <20040216220757.GA21424@frogman.motivity.ca> <20040217060114.GE21424@frogman.motivity.ca> Message-ID: <40320B24.6020104@hq.idt.net> Thank you Vance! I couldn't have excpected a better response. :-) Serge Vance Shipley wrote: > Curiosity got the better of me so I ran some benchmarks. > > The attached runs four different versions a gen_server. > The first test is with a full 65K of {module, function} > tuples of generated atoms. Each test is a loop of 1000 > gen_server:call. > > CNT ACC OWN > list 14605, 2874.423, 11382.772 > gb_trees 14632, 163.546, 578.699 > ets 14631, 148.579, 523.257 > tuple of tuples 14632, 146.690, 512.442 > > > This is the output of fprof:analyse. Obviously the > list version is not effecient. The others seem > equivalent. > > With only 3000 random entries: > > list 14647, 221.448, 814.819 > gb_trees 14648, 154.442, 551.877 > ets 14648, 155.908, 558.271 > > > The list implentation isn't so bad now. There > doesn't seem to be much difference in the others. > I'm now satisfied that my gb_trees method is just > as effecient as an ets table. > > -Vance From jonathan@REDACTED Tue Feb 17 13:48:39 2004 From: jonathan@REDACTED (jonathan@REDACTED) Date: Tue, 17 Feb 2004 12:48:39 -0000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <200402170155.i1H1tWCl145950@atlas.otago.ac.nz> Message-ID: <40320DA7.4426.37E43A@localhost> > Now Simula-67 was developed precisely to support > object-oriented simulation. But Simula had TWO key features. OO was > one, and (simulated) concurrency was the other. Simula simulations > basically used co-operative multithreading. Bjarn Stroustrup, who > invented C++, was familiar with Simula 67, and invented it in order to > do the kind of simulations he was familiar with in a C-friendly/Algol-hostile > milieu. Surprise surprise: the Cfront implementation of C++ from AT&T > had TWO key features. OO was one, and (simulated) concurrency was the > other (the Task Library, chapter 2 of the AT&T C++ library manual). Interesting - I'd never heard this. > For what it's worth, there is a software development method called > Jackson Structured Programming, developed years ago and used for serious > EDP systems. One of the ideas in JSP is that you design your program as > a collection of thousands of interacting concurrent processes/objects, > and then "invert" the design to get your COBOL, because you obviously > can't *really* have thousands of concurrent processes (:-). Again, that's interesting. I've always heard good things about JSP. From jonathan@REDACTED Tue Feb 17 13:48:39 2004 From: jonathan@REDACTED (jonathan@REDACTED) Date: Tue, 17 Feb 2004 12:48:39 -0000 Subject: highlight erlang editor for windows In-Reply-To: Message-ID: <40320DA7.8635.37E481@localhost> On 17 Feb 2004 at 9:37, Robert Balogh wrote: > Hej, > > I'd like to ask you can I download somewhere a highlight erlang editor for > windows? > > thanks for your help, > > regards, > /Robi > > _________________________________________________________________ > Protect your PC - get McAfee.com VirusScan Online > http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 > If you're like most Windows users (eg me) you'll find Emacs confusing to use until you also download and install a CUA package, so that standard ctl-keys like Ctrl-X work. (After you've done this it's terrific.) Just google "cua" and "emacs" and you should get an explanation and a site to download the right packages from. If this doesn't work then mail me and I'll send over my own emacs customization file. - Jonathan Coupe From klacke@REDACTED Tue Feb 17 14:42:36 2004 From: klacke@REDACTED (klacke@REDACTED) Date: Tue, 17 Feb 2004 14:42:36 +0100 Subject: Embedded System with Yaws on Windows In-Reply-To: <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> Message-ID: <20040217134236.GA7491@hyber.org> On Thu, Feb 12, 2004 at 08:32:44AM +0200, Rudolph van Graan wrote: > Hi, > > > >ve been reviewing the code and searching the Yaws and Erlang list > >archives, looking/hoping for a solution short of the "surgery" that > >you mention. So far, the answer (if there is one) eludes me. But I'm > >not the brightest guy in the world... Hopefully someone in the group > >can help us. If not, I'll attempt to develop and post a "Cygwin Free" > >patch. I'm sure that we're not the only ones who desire this > >capability. > > > > Put it this way, I've managed to almost de-cygwin yaws last night, but > maybe Klacke can tell us what we really need to do, or can do, to make > yaws work? What specifically does yaws use the setuid driver for? Is it > only for the case where one would install yaws as root and then change > the uid to something else? This is what the driver is used for. In the yaws code, the configure script on cygwin disables the driver entirely. The set_uid feature isn't suppurted under cygwin. The reason for this was just to make yaws more easily deployed on win32 platform. I don't understand why you are fiddling with the set_uid driver since it was removed from win32 build looong time ago. What's worse in the de-cygwin procedure though are the Makefiles and the build scripts. On the other hand if you want to run yaws embedded inside your other win32/erl app, all you need to do is: - drop yaws source into your app/lib/yaws Integrate with build procedure of your app. Take a look at build procedure under cygwin in order to figure out how to not use the linked in driver code at all. Basically all it takes is to not have the driver installed at all and _not_ use the the 'username' feature in the config. This should be pretty straightforward ...... /klacke -- Claes Wikstrom -- Caps lock is nowhere and http://www.hyber.org -- everything is under control From vlad_dumitrescu@REDACTED Tue Feb 17 14:44:14 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 14:44:14 +0100 Subject: Pattern matching vs. ETS lookups References: Message-ID: ----- Original Message ----- From: "Tony Rogvall" > I am also trying that, but like you said, it is STILL compiling????? > What on earth is going on in the compiler??? I tried it too, and it took almost 15 minutes. (emacs@REDACTED)3> timer:tc(compile, file, ["a"]). {852392990,{ok,a}} Now, it might be interesting to notice that if all branches return the same term, then the compiling time becomes significantly shorter. /Vlad From spearce@REDACTED Tue Feb 17 15:07:37 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 17 Feb 2004 09:07:37 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: <4030E928.10491.D7A0EF@localhost> <20040216223827.GA27585@spearce.org> Message-ID: <20040217140737.GB28578@spearce.org> Yes, it is. Its now driving me mad. I have to go to my day job now where I'll be writing Java code, and I'm not happy about that.... but its better than the Windows serial port APIs! Maybe drugs will help me to get the code right... after all, the folks who designed and implemented these APIs in Windows must have been on drugs too when they did this! I'd be on 100% UNIX (Linux) in a heartbeat if I could. Unfortuantely, I think some nodes will need serial port IO on Windows. :-( At least the Linux developers don't work when their high on crack! Vlad Dumitrescu wrote: > From: "Shawn Pearce" > > I'm wodering how I can go back to my day job tomorrow after a week of > > vacation and several days of Erlang hacking. I write Java for a > > living. :-( > > Well, it's going to be difficult :-) I know, I am going through it myself. What > keeps me going is thinking how simple it would be to rewrite the whole system in > Erlang. > > I also thought about trying some heavy sedation, but since I am driving from and > to home, it's not a good idea :-P -- Shawn. Tonight you will pay the wages of sin; Don't forget to leave a tip. From joachim.durchholz@REDACTED Tue Feb 17 15:40:53 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Tue, 17 Feb 2004 15:40:53 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040217122439.GD3109@cgey.com> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> Message-ID: <403227F5.90405@web.de> Mickael Remond wrote: > Thread can be created more quickly. However, I do not know to which > extend the 2.6 thread are lighter than 2.4. > If the memory taken for each thread is still important, this is a direct > and quickly reached limitation to the number of thread you can manage. AFAIK the overhead of a Unix process over a thread is stuff like the command line, environment variables, and a table of file descriptors. I don't know how the exact layout is, but this shouldn't amount to more than a handful of KBytes. That's still more than the CPU context that must be swapped to RAM when switching threads, but not too much - modern processors typically take several hundred bytes or more. > You end up filling up the memory too quickly and soon start deterioating > performance. I don't think so - if you take a server with 1 GB RAM, the process vs. thread overhead will cut the number of processes you can serve from tens of billions to billions (under the worst-case assumption that threads don't use any local data on their own). As soon as every thread allocates a KByte of memory, the memory overhead diminishes to a factor of two, and it decreases further as each thread uses more memory. But even in the worst case, I suspect that the true bottleneck is the CPU, not RAM. The quoted IBM paper gave numbers for a concrete test run: a server with 9 GB of RAM and eight 700-MHz processors had a near-100% CPU usage, but just 36% memory usage (when serving 623 pages per second). More interesting is that server performance increased by a factor of six (!). Given that Yaws performance was ahead of Apache by a factor of roughly 2.5 (at least on the benchmarks posted by Joe), it would be very interesting to see how much Yaws profits from the new Linux kernel. Of course, since my server is a low-bandwidth machine, I'd be more interested in the results of a uniprocessor benchmark :-) Joe - would you or Ali be willing and able to publish the test configuration&data so that others with equipment and time at hand could repeat the tests? Regards, Jo -- Currently looking for a new job. From vlad_dumitrescu@REDACTED Tue Feb 17 17:02:44 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 17:02:44 +0100 Subject: Higher order receieve anybody References: Message-ID: ----- Original Message ----- From: "Joe Armstrong" > What Uffe and Vlad *really* need is a "higher order" receives ... > > The idea is to rewrite: > > receive > {a, X} -> ... > b -> > Y -> ... > end > > as > > F = fun({a,X}) -> ... > (b) -> ... > (Y) -> ... > end, > Z = receive F, Hi Joe, I have a headache today, so I am not sure I understand what you mean (when it comes to what we discussed before). If you have some time to explain, I wil be very happy :-) What we need is to be able to dynamically insert clauses in the fun (or receive), so that system messages get processed. If matching incoming messages is done just on F's clauses (i.e. {a, X}, b and Y), then I don't see any difference from what we have today. If however the compiler would expand G = fun({m,X}) -> ... (z) -> ... (Y) -> ... end, F = fun({a,X}) -> ... (b) -> ... (Y) -> G(Y) end, receive F, into something equivalent to receive {a,X} -> ... b -> ... {m,X} -> ... z -> ... Y -> ... end, then I clearly see the point. I think it would work only if G is a fun (or possibly a local function), because ordinary external functions may change at runtime and we'd need to recompile dependent modules. Was it something like this you meant? best regards, Vlad From vlad_dumitrescu@REDACTED Tue Feb 17 17:05:26 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 17:05:26 +0100 Subject: any ex11 news? Message-ID: Hi Joe, Did you had time to work anything more on ex11? I think you said at one time that there are some important changes in the pipeline (or so I understood), and I thought I'd wait for them. regards, Vlad From jamesh@REDACTED Tue Feb 17 17:12:53 2004 From: jamesh@REDACTED (James Hague) Date: Tue, 17 Feb 2004 10:12:53 -0600 Subject: So now all I'd like in Erlang is... Message-ID: Joe Armstrong wrote: >So now all I'd like in Erlang is: > >1) Higher order code Could you elaborate? >2) *Proper* structs Has any progress been made toward this one? At least some internal political discussion at Ericsson? :) >3) !! >4) Higher order receive >5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard C) How tiny do you want to go? If nothing else, I'd like to see most of the BEAM opcode combination stuff in beam_load.c be rolled into the compiler. This would be a big win in terms of reducing complexity. James From vlad_dumitrescu@REDACTED Tue Feb 17 19:45:03 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 19:45:03 +0100 Subject: So now all I'd like in Erlang is... References: Message-ID: From: "James Hague" > Joe Armstrong wrote: > >So now all I'd like in Erlang is: > >1) Higher order code > Could you elaborate? Yes, please! > >3) !! How could we have timeouts with "!!"? > >5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard C) I feel this should mean removing the 'query' reserved keyword and Mnemosyne-query LCs from the "regular" parser/compiler, and implementing them as extensions in a general way. Or? /Vlad From mlogan@REDACTED Tue Feb 17 19:58:08 2004 From: mlogan@REDACTED (Martin J. Logan) Date: 17 Feb 2004 12:58:08 -0600 Subject: Read terms from the command line Message-ID: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> Anyone know how to read erlang terms off the command line. Specifically I would like to call an erlang function via erl -s or something similar and pass the function terms. Does anyone know of a method to "consult" chars passed in from the command line. Martin From joe@REDACTED Tue Feb 17 20:43:06 2004 From: joe@REDACTED (Joe Armstrong) Date: Tue, 17 Feb 2004 20:43:06 +0100 (CET) Subject: So now all I'd like in Erlang is... In-Reply-To: Message-ID: On Tue, 17 Feb 2004, James Hague wrote: > Joe Armstrong wrote: > > >So now all I'd like in Erlang is: > > > >1) Higher order code > > Could you elaborate? First order code is code that I can manipulate as regular data. I'd really like a do thinks like this ... % define a module Mod = {{export,[{foo,2},{bar,1}....]}, {code, [{foo,2,fun(X,Y) -> ...end}, {bar,1,fun(X) -> ... end}]}}, % compile it Code = compile(Mod), % call code without "publishing it" Code:foo(1,2) % publish it publish(Code, bar), % now you can use it bar:foo(1,2), ... % modify it Code1 = replace_fun(Code, foo,2,fun(X,Y) -> ... end) % test it Code1:foo(1,2) % publish publish(Code, bar) % ... % get the code back Code2 = getCode(bar) ... GC should sweep away unreachable code There should be multiple versions of old code (not just two) > > >2) *Proper* structs > > Has any progress been made toward this one? At least some internal > political discussion at Ericsson? :) > > >3) !! > >4) Higher order receive > >5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard > C) > > How tiny do you want to go? > Without any space allocated for processes I'd like the run-time down to less than a 500KB - a decent app should be less than 1 Meg. > If nothing else, I'd like to see most of the BEAM opcode combination stuff > in beam_load.c be rolled into the compiler. This would be a big win in > terms of reducing complexity. I am current playing with the idea that one should "write as much in Erlang as possible and write as little C as possible" and also if possible write a program to write the C rather than writing the C myself. I am experimenting with a code generator, you give it rules like this: {{pushAtom, a}, {opCode, i}, "*Code++ = &&Opcode; *Code++ = *codeBuff++;" "*Stop++ = *PC++;"} This means there is an instruction pushAtom with argument an Atom to serialize it generate an opcode followed by an integer. To deserialise it and make it into threaded code evaluate *Code++=... and to execute execute do "*Stop++ = ..." etc. My code generator splits out chucks of C and Erlang which get glued together to make the back-end of the assembler and the input routines for deserialising the data and the inner loop of the the emulator. It is my hope that even tricky things like GC can be written in a combination of C and Erlang. I can imagine Erlang (say) administering the GC sweeps and making policy decisions about when to do GC etc and just write a single process stack/heap collector that is triggered by the Erlang process. Writing C is like performing open brain surgery - it seems easier to write programs which write C rather than writing it myself - that way you only have to get the code generator right *once* rather than getting every single C program right. /Joe > > James > From joe@REDACTED Tue Feb 17 20:48:03 2004 From: joe@REDACTED (Joe Armstrong) Date: Tue, 17 Feb 2004 20:48:03 +0100 (CET) Subject: any ex11 news? In-Reply-To: Message-ID: I have totally rewritten the Xauthentication routines :-) and use unix domain sockets now. Multiple screens will be supported I've had a lot of feed back from many people - but havn't yet put in all the patches. I've no time to do this now - I'm off to Budapest tomorrow to hold a talk about <> :-) Hopefully next week. Cheers /Joe On Tue, 17 Feb 2004, Vlad Dumitrescu wrote: > Hi Joe, > > Did you had time to work anything more on ex11? I think you said at one time > that there are some important changes in the pipeline (or so I understood), and > I thought I'd wait for them. > > regards, > Vlad > From cpressey@REDACTED Tue Feb 17 21:04:22 2004 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 17 Feb 2004 12:04:22 -0800 Subject: Higher order receieve anybody In-Reply-To: References: Message-ID: <20040217120422.0c06e71c.cpressey@catseye.mine.nu> On Tue, 17 Feb 2004 10:10:31 +0100 (CET) Joe Armstrong wrote: > What Uffe and Vlad *really* need is a "higher order" receives ... > > The idea is to rewrite: > > receive > {a, X} -> ... > b -> > Y -> ... > end > > as > > F = fun({a,X}) -> ... > (b) -> ... > (Y) -> ... > end, > Z = receive F, > > > If we introduce an infix ? operator, we'd get: > > Z = ?F s/infix/prefix/g Does this mean that funs will be able to have an 'after' clause? :) -Chris From vlad_dumitrescu@REDACTED Tue Feb 17 21:22:47 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 17 Feb 2004 21:22:47 +0100 Subject: any ex11 news? References: Message-ID: From: "Joe Armstrong" > I have totally rewritten the Xauthentication routines :-) and use > unix domain sockets now. Great, but I hope it's not unix sockets *only*. Some of us are on Windows :-) > I've no time to do this now - I'm off to Budapest tomorrow to hold > a talk about <> :-) No hurry, I was just wondering. Good luck! /Vlad From tony@REDACTED Tue Feb 17 22:55:09 2004 From: tony@REDACTED (Tony Rogvall) Date: Tue, 17 Feb 2004 22:55:09 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: Message-ID: On Tuesday, Feb 17, 2004, at 20:43 Europe/Stockholm, Joe Armstrong wrote: > On Tue, 17 Feb 2004, James Hague wrote: > >> Joe Armstrong wrote: >> >>> So now all I'd like in Erlang is: >>> >>> 1) Higher order code >> >> Could you elaborate? > > First order code is code that I can manipulate as regular data. > > I'd really like a do thinks like this ... > > % define a module > Mod = {{export,[{foo,2},{bar,1}....]}, > {code, [{foo,2,fun(X,Y) -> ...end}, > {bar,1,fun(X) -> ... end}]}}, > % compile it > Code = compile(Mod), > % call code without "publishing it" > Code:foo(1,2) > % publish it > publish(Code, bar), > % now you can use it > bar:foo(1,2), ... > % modify it > Code1 = replace_fun(Code, foo,2,fun(X,Y) -> ... end) > % test it > Code1:foo(1,2) > % publish > publish(Code, bar) > % ... > % get the code back > Code2 = getCode(bar) > ... > > GC should sweep away unreachable code > > There should be multiple versions of old code (not just two) > I have implemented this once, in the (in)famous Multi Pro Erlang. It worked like a charm. I also thought a bit of adding functionality to upgrade code in generic servers by using "unpublished" code. The implementation overloaded register and unregister instead of publish/unpublish, it used a new dynamic type "Module" to distinguish the cases. Of course the Module had a external representation as any Erlang Term so loading code and register looked like. {ok, Bin} = file:read_file("mymod.beam"), Mod = binary_to_term(Bin), register(mymod, Mod). In a multipro environment the register part was a bit tricky but we (me and Pekka H) think we solve it. ....... > > I am current playing with the idea that one should "write as much in > Erlang as possible and write as little C as possible" and also if > possible write a program to write the C rather than writing the C > myself. > > I am experimenting with a code generator, you give it rules like > this: > > {{pushAtom, a}, {opCode, i}, "*Code++ = &&Opcode; > *Code++ = *codeBuff++;" > > "*Stop++ = *PC++;"} > > This means there is an instruction pushAtom with argument an Atom to > serialize it generate an opcode followed by an integer. To deserialise > it and make it into threaded code evaluate *Code++=... and to execute > execute do "*Stop++ = ..." etc. > > My code generator splits out chucks of C and Erlang which get glued > together to make the back-end of the assembler and the input routines > for deserialising the data and the inner loop of the the emulator. > > It is my hope that even tricky things like GC can be written in a > combination of C and Erlang. I can imagine Erlang (say) administering > the GC sweeps and making policy decisions about when to do GC etc and > just write a single process stack/heap collector that is triggered by > the Erlang process. > > Writing C is like performing open brain surgery - it seems easier to > write programs which write C rather than writing it myself - that way > you only have to get the code generator right *once* rather than > getting every single C program right. > (CRAZY IDEA SECTION) Ok what about Forth, the forth has the tiny interpreter (talking about a few bytes). I have had a project that has been in my mind for years. That is to rewrite the erlang runtime system in forth (yes I have written a forth system capable of such a task). Then let the erlang compiler generate forth (in some nice loadable format). When loading such a module a range of transforms (even jit assembler stuff is available) (I do however think that this require an even bigger brain surgery than writing C code :-) Forth is truly mind boggling /Tony From bluewally@REDACTED Wed Feb 18 00:46:55 2004 From: bluewally@REDACTED (Wally Cash) Date: Tue, 17 Feb 2004 18:46:55 -0500 Subject: Embedded System with Yaws on Windows In-Reply-To: <20040217134236.GA7491@hyber.org> References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> <20040217134236.GA7491@hyber.org> Message-ID: Klacke, Thanks for your help. This is precisely the info. was needed. I really should be better versed on cross platform compatability issues with cygwin. As an aside, thanks for Yaws. It truly is a beautiful piece of work! Regards --Wally On Tue, 17 Feb 2004 14:42:36 +0100, wrote: > On Thu, Feb 12, 2004 at 08:32:44AM +0200, Rudolph van Graan wrote: >> Hi, >> >> >> >ve been reviewing the code and searching the Yaws and Erlang list >> >archives, looking/hoping for a solution short of the "surgery" that >> >you mention. So far, the answer (if there is one) eludes me. But I'm >> >not the brightest guy in the world... Hopefully someone in the group >> >can help us. If not, I'll attempt to develop and post a "Cygwin Free" >> >patch. I'm sure that we're not the only ones who desire this >> >capability. >> > >> >> Put it this way, I've managed to almost de-cygwin yaws last night, but >> maybe Klacke can tell us what we really need to do, or can do, to make >> yaws work? What specifically does yaws use the setuid driver for? Is it >> only for the case where one would install yaws as root and then change >> the uid to something else? > > > > This is what the driver is used for. In the yaws code, the configure > script on cygwin disables the driver entirely. The set_uid feature > isn't suppurted under cygwin. The reason for this was just to make > yaws more easily deployed on win32 platform. > > I don't understand why you are fiddling with the set_uid driver > since it was removed from win32 build looong time ago. > > What's worse in the de-cygwin procedure though are the > Makefiles and the build scripts. On the other hand if you want > to run yaws embedded inside your other win32/erl app, all you > need to do is: > > - drop yaws source into your app/lib/yaws > > Integrate with build procedure of your app. Take a look > at build procedure under cygwin in order to figure out how > to not use the linked in driver code at all. Basically all it takes > is to not have the driver installed at all and _not_ use the > the 'username' feature in the config. > > > > This should be pretty straightforward ...... > > > > /klacke > > -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ From spearce@REDACTED Wed Feb 18 01:30:47 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 17 Feb 2004 19:30:47 -0500 Subject: Higher order receieve anybody In-Reply-To: References: Message-ID: <20040218003047.GA22613@spearce.org> Joe Armstrong wrote: > 1) Higher order code Then we'd have LISP. :-) > 2) *Proper* structs Ah, yes, this debate. When will they be ready? :-) > 3) !! Timeouts are a concern. Perhaps the timeout can be set as a process flag: process_flag(default_rpc_timeout, Ms). With the timeout throwing an exit: exit({rpctimeout, To, Message}). This is really just a parse transform: begin Tag = make_ref(), To ! {rpc, Tag, Message}, receive {reply, Tag, Response} -> Response; after process_flag(default_rpc_timeout) -> exit({rpctimeout, To, Message}) end end We just need the process flag. :-) But, if !! ever comes into Erlang/OTP, it better work with the gen_server call format. :) > 4) Higher order receive Well, a better receive over all that does everything we're all wishing receive could do would be great. Especially if I could write: receive {java, WorkingProgram} -> {no_more_work_for_shawn, WorkingProgram} end and quit my day job. :-) > 5) A *tiny* implementation (written 99% in Erlang and 1% in > ANSI standard C) Ever since I was introduced to Erlang right after the initial open source release, I've thought about doing this for fun. Squeak (the Smalltalk created by Disney I believe) is built like this. Most of the Squeak runtime is actually Smalltalk code compiled with a simple compiler. Only some of the language and its features is supported when the low level parts of the runtime get built, but I've heard that even the GC in Squeak is written in Smalltalk. I've often thought over the years that an Erlang runtime could be built by creating a primitive Erlang language that was a subset of most of the language, with perhaps destructive updates allowed against binaries (and only binaries). This would let you map the memory of your host into the runtime, then write the entire GC, tuple BIFs, etc in Erlang code. When that turns into native machine code, it should come out close to what the hand written C would have been. Clearly destructive updates would be limited to only a very small segment of code, and would be disallowed by the real code loader used at runtime, to prevent users from trying to use the really low level feature. A few times I've theorized to myself that it may be possible to do this in pure Erlang, without destructive update, so long as a copying garbage collector is used to manage the heap. One implementation might be to model each half-heap as a binary. Allocation is performed by splitting the half-heap binary in two parts, with the A part being the space used by the new cons cell, tuple, binary, etc. and the B part being the remaining free space, which is now just a slightly smaller binary. The problem is, how do you update the A part and fill in the tuple's data, or the cons cell data, etc. initially in a single assignment, non-desctructive language. :) I've just never gotten to this project, I've always had something else that was distracting me. I wish I had, because I'm getting into Erlang more, and wondering why I didn't try to do this several years ago instead of screwing around with Java. -- Shawn. share, n.: To give in, endure humiliation. From spearce@REDACTED Wed Feb 18 01:51:49 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 17 Feb 2004 19:51:49 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <403227F5.90405@web.de> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> Message-ID: <20040218005149.GB22613@spearce.org> Joachim Durchholz wrote: > AFAIK the overhead of a Unix process over a thread is stuff like the > command line, environment variables, and a table of file descriptors. I > don't know how the exact layout is, but this shouldn't amount to more > than a handful of KBytes. > That's still more than the CPU context that must be swapped to RAM when > switching threads, but not too much - modern processors typically take > several hundred bytes or more. This is quite correct, but really the process overhead goes into: - file descriptor table - resource limit management and tracking - environment (which is in userland not in the kernel) - command line (also in userland, not in kernel) - page tables (in kernel, and can be a memory hog) - private data pages holding global variables When you have just a handful of globals, the data page which holds them can be mostly empty. This really sucks up memory quick when you spawn a large number of the same processes. The CPU context is associated with the kernel level thread, so its going to be there no matter which you are using, process or a kernel thread. Interstingly one of the big performance killers during process context switches is the loss of the TLB cache. This is caching the most frequently accessed part of the page tables, and modern processors just don't have enough TLB cache space. Some require the entire TLB to be tossed whenever the kernel switches processes, some can cache parts of the TLB in case the process comes back quickly. But thus far I've seen that TLB misses can easily kill your performance. One reason Erlang runs so well (and any other very tight user space implementation) is they can eliminate all of the memory overheads, making an entire process fit into just a cache line or two in the processor's data cache. When an entire Erlang process can get swapped in by just one or two memory loads, and has no TLB miss penalties, etc, life can be very, very good. Also due to the effects of the relatively small i-cache on some processors, a well written emulator can in fact run faster than native code on very big applications. If the application has very poor cache locatily in its instruction stream (randomly jumping to different functions) the i-cache can have a hard time keeping up. But if you move all of the code into the much larger d-cache (as in the case of an emulator) you can make the emulator fly as a much higher percentage of the application can be stored in the d-cache. Now this is easily worked around by using tools to reorder your native code functions in the huge application such that they occur in execution order. I've seen this easily give a 40% performance boost (or more!) on x86 processors. If you do this, you should easily beat the emulator. :-) > >You end up filling up the memory too quickly and soon start deterioating > >performance. > > I don't think so - if you take a server with 1 GB RAM, the process vs. > thread overhead will cut the number of processes you can serve from tens > of billions to billions (under the worst-case assumption that threads > don't use any local data on their own). > As soon as every thread allocates a KByte of memory, the memory overhead > diminishes to a factor of two, and it decreases further as each thread > uses more memory. > But even in the worst case, I suspect that the true bottleneck is the > CPU, not RAM. Its more like RAM bandwidth. Your CPU is most likely stalling on all of the context switches due to the amount of data it must keep swapping on and off of the chip core. Cycling through a bunch of registers ain't cheap. And whacking your pipeline on a very deeply pipelined processor is no walk in the park either. Then take into account the d-cache, i-cache and TLB misses you incur on each switch, and things go downhill very fast. Of course, there are applications (like Mozilla!) that will just consume all memory on your machine, and then some, so you better not run multiple copies of them at once. :-) > The quoted IBM paper gave numbers for a concrete test run: a server with > 9 GB of RAM and eight 700-MHz processors had a near-100% CPU usage, but > just 36% memory usage (when serving 623 pages per second). > More interesting is that server performance increased by a factor of > six (!). Given that Yaws performance was ahead of Apache by a factor of > roughly 2.5 (at least on the benchmarks posted by Joe), it would be very > interesting to see how much Yaws profits from the new Linux kernel. Well, given that erts is bound to a single processor, you would need to create a cluster of erts nodes, all running yaws, with some type of load balancing front end. This is one area Apache really shines in, as it easily allows this to be setup: because Apache is multi-process already, it can easily share the single TCP server socket with all of its siblings and decide who gets the next request. Does anyone think it might be possible to modify gen_tcp in such a way that we could use multiple nodes on the same system all bound to the same TCP port, and using some sort of accept lock between them? I'd think this could be done something like this: % Setup a server socket, but let it be shared by this Erlang node and all % other process on this box. gen_tcp:accept(... [shared]) % Have this node take over accepting all new connections. This just pokes % the socket into the erts event loop. gen_tcp:enable_accept(Port) % Have this node stop accepting new connections. This just removes the % socket from the erts event loop. gen_tcp:disable_accept(Port) It might be necessary however (for performance reasons) to let the low level C driver also perform its own accept lock using a sys-v IPC sem, flock, fcntl, etc, on top of the Erlang managed enable and disable. If the socket is enabled, then the driver should attempt to grab the accept lock, and only when it wins it it puts it into the erts event loop. Clearly this might be difficult as the driver cannot block while trying to grab the accept lock. Note that Linux doesn't require the accept lock I believe... I think its accept only returns the socket to one process. But I'm not positive. -- Shawn. Velilind's Laws of Experimentation: (1) If reproducibility may be a problem, conduct the test only once. (2) If a straight line fit is required, obtain only two data points. From spearce@REDACTED Wed Feb 18 01:58:25 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 17 Feb 2004 19:58:25 -0500 Subject: So now all I'd like in Erlang is... In-Reply-To: References: Message-ID: <20040218005825.GC22613@spearce.org> Joe Armstrong wrote: > I'd really like a do thinks like this ... > > % define a module > Mod = {{export,[{foo,2},{bar,1}....]}, > {code, [{foo,2,fun(X,Y) -> ...end}, > {bar,1,fun(X) -> ... end}]}}, > % compile it > Code = compile(Mod), > % call code without "publishing it" > Code:foo(1,2) I've often wondered why Erlang code is: foo(X) -> ok. and not: Foo = fun(X) -> ok end. with call sites using: Foo(x). instead of: foo(x). In other words, why are named functions different from lambdas? Why not make all named functions actually global variables which are assigned to a lambda when the module loads? As soon as you do this, it becomes possible to do things like: LoadDetsFile = fun() -> ... pull a dets file into a list .. end. SomeConstant = LoadDetsFile(). LookupUser = fun(Name) -> Lists:Keysearch(Name, 1, SomeConstant) end. :-) > There should be multiple versions of old code (not just two) Yippee! With this we can get rid of that *killed* message I love so much when you load the module twice and your servers are plain Erlang servers which are wedged in a receive call. :-) And I can blow up memory footprint by loading modules every few minutes and never getting the existing processes to switch to the new version. Oh, that's what I do in Java at work. :) This I think is a really good thing. It removes some risk associated with code upgrades, and upgrading too quickly. > Without any space allocated for processes I'd like the run-time down to > less than a 500KB - a decent app should be less than 1 Meg. Wow. That would be sweet if the runtime could get that small. I think only a handful of programs, like say agetty on Linux, run in that tiny of a heap anymore. > Writing C is like performing open brain surgery - it seems easier to > write programs which write C rather than writing it myself - that way > you only have to get the code generator right *once* rather than > getting every single C program right. This is why I try to write Java code generators, and not Java code. I once did an Erlang code generator in Erlang, and for whatever reason, found it more painful than I'd like to remember... I'm all for building a micro-Erlang with no human written C code in it at all. :-) -- Shawn. Once you've tried to change the world you find it's a whole bunch easier to change your mind. From fritchie@REDACTED Wed Feb 18 07:27:27 2004 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Wed, 18 Feb 2004 00:27:27 -0600 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: Message of "Tue, 17 Feb 2004 19:51:49 EST." <20040218005149.GB22613@spearce.org> Message-ID: <200402180627.i1I6RR52023402@snookles.snookles.com> >>>>> "sp" == Shawn Pearce writes: sp> Does anyone think it might be possible to modify gen_tcp in such a sp> way that we could use multiple nodes on the same system all bound sp> to the same TCP port, and using some sort of accept lock between sp> them? A slightly more oldfashioned way would be to have a single Erlang node do all of the accepting and then pass the file descriptor to another node via a UNIX domain socket. Yet another reason to include a UNIX domain socket driver along with ERTS. Bad Scott, no biscuit for you! -Scott From bjorn@REDACTED Wed Feb 18 09:09:39 2004 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 18 Feb 2004 09:09:39 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: References: Message-ID: James Hague writes: > Joe Armstrong wrote: > > >So now all I'd like in Erlang is: > > > >1) Higher order code > > Could you elaborate? > > >2) *Proper* structs > > Has any progress been made toward this one? At least some internal > political discussion at Ericsson? :) Yes, we have discussed it. Joe's ideas for structs are good, but we are very careful with actually starting to implementing it, because we must essentially get everything right the first time. People will start using struct immediately and it will be very hard to go back and change anything. The issues that I see with structs are that they will be slower than records, at least for read access. Therefore, they may not be usuable in all circumstances where records are used today. > > >3) !! > >4) Higher order receive > >5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard > C) > > How tiny do you want to go? > I don't see the point with having a tiny implementation. Most important for our customers are stability and speed. If that makes the implementation more complex (and it does), that's OK. However, we don't want NEEDLESS complexity. Some things are still too complicated, and we are working on reducing needless complexity and removing options that are not used. Unfortunately, having to be backwards compatible prevents us from making all changes we want. > If nothing else, I'd like to see most of the BEAM opcode combination > stuff in beam_load.c be rolled into the compiler. This would be a > big win in terms of reducing complexity. I doubt that. The Beam loader is certainly complex, but it is complexity isolated in a single place. Having the loader there keeps the compiler simpler, and allows us to keep the beam file format compatible. Essentially, the format is the same from R5B up to R10B and beyond. (In practice, a few minor details prevent you from loading and running most R5B modules in R9B and higher, but you can always run code compiled several releases back.) /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From erlang@REDACTED Wed Feb 18 09:12:56 2004 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 18 Feb 2004 08:12:56 +0000 Subject: Erlang + Forth?!? In-Reply-To: References: Message-ID: <20040218081256.1687a75b.erlang@manderp.freeserve.co.uk> Good Lord! I had forgotten that remarkable language! I have never used it, but over 20 years ago I pondered buying a Jupiter ACE instead of a Sinclair Spectrum, but was beguiled by the spectrum "colour" capability. Young fool! (-: Has anyone heard of or remember the Jupiter ACE, made by Jupiter Cantab? It was the only interesting competitor of the Sinclair ZX Spectrum in the 1980's, and it's native language was forth, not BASIC. It beat the pants off the competition in terms of pure speed. Pete. On Tue, 17 Feb 2004 22:55:09 +0100 Tony Rogvall wrote: > > On Tuesday, Feb 17, 2004, at 20:43 Europe/Stockholm, Joe Armstrong > wrote: > > > On Tue, 17 Feb 2004, James Hague wrote: > > > >> Joe Armstrong wrote: > >> > >>> So now all I'd like in Erlang is: > >>> > >>> 1) Higher order code > >> > >> Could you elaborate? > > > > First order code is code that I can manipulate as regular data. > > > > I'd really like a do thinks like this ... > > > > % define a module > > Mod = {{export,[{foo,2},{bar,1}....]}, > > {code, [{foo,2,fun(X,Y) -> ...end}, > > {bar,1,fun(X) -> ... end}]}}, > > % compile it > > Code = compile(Mod), > > % call code without "publishing it" > > Code:foo(1,2) > > % publish it > > publish(Code, bar), > > % now you can use it > > bar:foo(1,2), ... > > % modify it > > Code1 = replace_fun(Code, foo,2,fun(X,Y) -> ... end) > > % test it > > Code1:foo(1,2) > > % publish > > publish(Code, bar) > > % ... > > % get the code back > > Code2 = getCode(bar) > > ... > > > > GC should sweep away unreachable code > > > > There should be multiple versions of old code (not just two) > > > I have implemented this once, in the (in)famous Multi Pro Erlang. > It worked like a charm. > I also thought a bit of adding functionality to upgrade code in generic > servers by using > "unpublished" code. > The implementation overloaded register and unregister instead of > publish/unpublish, it used a new > dynamic type "Module" to distinguish the cases. Of course the Module > had a external representation > as any Erlang Term so loading code and register looked like. > > {ok, Bin} = file:read_file("mymod.beam"), > Mod = binary_to_term(Bin), > register(mymod, Mod). > > In a multipro environment the register part was a bit tricky but we (me > and Pekka H) think we > solve it. > > ....... > > > > > I am current playing with the idea that one should "write as much in > > Erlang as possible and write as little C as possible" and also if > > possible write a program to write the C rather than writing the C > > myself. > > > > I am experimenting with a code generator, you give it rules like > > this: > > > > {{pushAtom, a}, {opCode, i}, "*Code++ = &&Opcode; > > *Code++ = *codeBuff++;" > > > > "*Stop++ = *PC++;"} > > > > This means there is an instruction pushAtom with argument an Atom to > > serialize it generate an opcode followed by an integer. To deserialise > > it and make it into threaded code evaluate *Code++=... and to execute > > execute do "*Stop++ = ..." etc. > > > > My code generator splits out chucks of C and Erlang which get glued > > together to make the back-end of the assembler and the input routines > > for deserialising the data and the inner loop of the the emulator. > > > > It is my hope that even tricky things like GC can be written in a > > combination of C and Erlang. I can imagine Erlang (say) administering > > the GC sweeps and making policy decisions about when to do GC etc and > > just write a single process stack/heap collector that is triggered by > > the Erlang process. > > > > Writing C is like performing open brain surgery - it seems easier to > > write programs which write C rather than writing it myself - that way > > you only have to get the code generator right *once* rather than > > getting every single C program right. > > > (CRAZY IDEA SECTION) > Ok what about Forth, the forth has the tiny interpreter (talking about > a few bytes). I have had a project > that has been in my mind for years. That is to rewrite the erlang > runtime system in forth > (yes I have written a forth system capable of such a task). > Then let the erlang compiler generate forth (in some nice loadable > format). > When loading such a module a range of transforms (even jit assembler > stuff is available) > (I do however think that this require an even bigger brain surgery than > writing C code :-) > > Forth is truly mind boggling > > /Tony > -- "The Tao of Programming flows far away and returns on the wind of morning." From rvg@REDACTED Wed Feb 18 10:55:59 2004 From: rvg@REDACTED (Rudolph van Graan) Date: Wed, 18 Feb 2004 11:55:59 +0200 Subject: Embedded System with Yaws on Windows In-Reply-To: <20040217134236.GA7491@hyber.org> References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> <20040217134236.GA7491@hyber.org> Message-ID: Hi Klacke, > I don't understand why you are fiddling with the set_uid driver > since it was removed from win32 build looong time ago. My build insisted on using it... But read below, it was later fixed by shifting to cygwin. > What's worse in the de-cygwin procedure though are the > Makefiles and the build scripts. On the other hand if you want > to run yaws embedded inside your other win32/erl app, all you > need to do is: Our problem was that we didn't have a build procedure in Windows, other than plain erlang and (obviously) nothing compiled directly. I have subsequently installed a cygwin build environment and yes, everything worked this way around. Actually, for me the *biggest* problem is that I cannot get "target_system" to work in windows - hence we build on linux (.tar.gz) and then convert it manually to windows. This is where the de-cygwin approach started. If I could build everything (and maybe I am just missing something obvious) from windows, I'd be happy to use it. On the topic... Do any of you have working code employed to start Yaws from code? I.e. like in the exact syntax to use to configure everything in "yaws.conf" in code? The one thing I did note regarding yaws on windows was the fact that if you want to specify "c:\web" as root-folder in yaws.conf, you have to specify it as "/web"... This immediately raises the question of how to specify "D:\web"..? -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2112 bytes Desc: not available URL: From richardc@REDACTED Wed Feb 18 11:33:16 2004 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 18 Feb 2004 11:33:16 +0100 (MET) Subject: Erlang + Forth?!? In-Reply-To: <20040218081256.1687a75b.erlang@manderp.freeserve.co.uk> References: <20040218081256.1687a75b.erlang@manderp.freeserve.co.uk> Message-ID: On Wed, 18 Feb 2004, Peter-Henry Mander wrote: > Good Lord! I had forgotten that remarkable language! > > I have never used it, but over 20 years ago I pondered buying a > Jupiter ACE instead of a Sinclair Spectrum, but was beguiled by the > spectrum "colour" capability. Young fool! (-: You did the right thing, I'm sure. And you could do pretty cool things with White Lightning Forth on the Speccy, if you wanted to use Forth. > Has anyone heard of or remember the Jupiter ACE, made by Jupiter > Cantab? It was the only interesting competitor of the Sinclair ZX > Spectrum in the 1980's, and it's native language was forth, not BASIC. > It beat the pants off the competition in terms of pure speed. Heard of it and read about it, yes. I think I even saw one once. I was not surprised that it wasn't a hit, though. Forth is a lot less friendly than Basic to a beginner. And of course, the speed advantage was only when you compared Forth - which uses, or rather is, threaded code - to interpreted Basic. But most interesting programs were written in assembler anyway, and I think the Speccy was the faster machine. (On a side note, the Spectrum Basic interpreter was made for compactness rather than speed. The source code was just stored in a tokenized form, and the interpreter actually used the same code both for syntax checking and for actual interpretation, with a flag that told it what mode it was in, i.e. "report errors" or "execute". But they did manage to cram a whole lot of functionality into that 16k Basic ROM.) The most interesting application of Forth that I saw in those days was in an advanced disassembler/debugger for the ZX Spectrum. (I can't recall the name.) It allowed you to write pieces of Forth code, to be executed upon a breakpoint. You could thus, in a very small amount of memory and with minimal speed penalty, do arbitrarily complicated tests to decide whether to continue or stop, or log/print information, etc. I don't know if there exist any other debuggers with similar functionality. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From bengt.kleberg@REDACTED Wed Feb 18 11:56:15 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Wed, 18 Feb 2004 11:56:15 +0100 Subject: Erlang + Forth?!? In-Reply-To: References: <20040218081256.1687a75b.erlang@manderp.freeserve.co.uk> Message-ID: <403344CF.3010803@ericsson.com> Richard Carlsson wrote: >was in an advanced disassembler/debugger for the ZX Spectrum. (I can't >recall the name.) It allowed you to write pieces of Forth code, to >be executed upon a breakpoint. You could thus, in a very small amount >of memory and with minimal speed penalty, do arbitrarily complicated >tests to decide whether to continue or stop, or log/print information, >etc. I don't know if there exist any other debuggers with similar >functionality. > > > when developing (part of) ose-delta, back in the early '90's, i used this kind of feature in a debugger. but i can not remember if it was the diab debugger or the other one (not so good compiler, green hill?). bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joachim.durchholz@REDACTED Wed Feb 18 12:15:13 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Wed, 18 Feb 2004 12:15:13 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040218005149.GB22613@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: <40334941.6070001@web.de> Shawn Pearce wrote: > Joachim Durchholz wrote: > >> AFAIK the overhead of a Unix process over a thread is stuff like >> the command line, environment variables, and a table of file >> descriptors. I don't know how the exact layout is, but this >> shouldn't amount to more than a handful of KBytes. That's still >> more than the CPU context that must be swapped to RAM when >> switching threads, but not too much - modern processors typically >> take several hundred bytes or more. > > This is quite correct, but really the process overhead goes into: > > - file descriptor table > - resource limit management and tracking > - environment (which is in userland not in the kernel) > - command line (also in userland, not in kernel) The above is the true overhead. The following applies whether the Erlang process is a full process or a thread: > - page tables (in kernel, and can be a memory hog) Agreed, but code sharing would (could?) apply to both. No difference here. > - private data pages holding global variables This is entirely independent of whether you're doing threads or processes. There's another potential: the run-time library. To make sure that it doesn't take up memory for every Unix process, it's probably best to put it into a shared library. > When you have just a handful of globals, the data page which holds > them can be mostly empty. This really sucks up memory quick when you > spawn a large number of the same processes. Agreed. If all threads are reasonably active, this is a small problem - the CPU will become a bottleneck long before RAM hits any limits. This applies to typical web servers like Yaws. Of course, if you have 100,000s of threads just waiting for a signal, then things are different. I don't know whether this situation is typical - anybody able to provide data points in this directions? > The CPU context is associated with the kernel level thread, so its > going to be there no matter which you are using, process or a kernel > thread. Interstingly one of the big performance killers during > process context switches is the loss of the TLB cache. This is > caching the most frequently accessed part of the page tables, and > modern processors just don't have enough TLB cache space. Some > require the entire TLB to be tossed whenever the kernel switches > processes, some can cache parts of the TLB in case the process comes > back quickly. But thus far I've seen that TLB misses can easily kill > your performance. TLB issues enter into the picture iff you consider running the Erlang interpreter in multiple OS processes. When comparing "interpreter with its own scheduler" to "machine code with OS scheduler", the TLB is just one of the things that make machine code execution faster - TLB misses just eat up part of the performance advantages of machine code, but they cannot get really slower (well, they could in really pathological circumstances). (I'm wondering whether CPUs that drop the entire TLB on every context switch should be considered mainstream or broken. Such a policy would certainly hurt interrupt performance.) > One reason Erlang runs so well (and any other very tight user space > implementation) is they can eliminate all of the memory overheads, > making an entire process fit into just a cache line or two in the > processor's data cache. When an entire Erlang process can get swapped > in by just one or two memory loads, and has no TLB miss penalties, > etc, life can be very, very good. Yup. However, if it can beat machine code with CPU context switches, the CPU design is very, very fishy :-) > Also due to the effects of the relatively small i-cache on some > processors, a well written emulator can in fact run faster than > native code on very big applications. If the application has very > poor cache locatily in its instruction stream (randomly jumping to > different functions) the i-cache can have a hard time keeping up. > But if you move all of the code into the much larger d-cache (as in > the case of an emulator) you can make the emulator fly as a much > higher percentage of the application can be stored in the d-cache. That's exactly the "fishy" case :-) >>> You end up filling up the memory too quickly and soon start >>> deterioating performance. >> >> I don't think so - if you take a server with 1 GB RAM, the process >> vs. thread overhead will cut the number of processes you can serve >> from tens of billions to billions (under the worst-case assumption >> that threads don't use any local data on their own). As soon as >> every thread allocates a KByte of memory, the memory overhead >> diminishes to a factor of two, and it decreases further as each >> thread uses more memory. But even in the worst case, I suspect that >> the true bottleneck is the CPU, not RAM. > > Its more like RAM bandwidth. Your CPU is most likely stalling on all > of the context switches due to the amount of data it must keep > swapping on and off of the chip core. Cycling through a bunch of > registers ain't cheap. And whacking your pipeline on a very deeply > pipelined processor is no walk in the park either. Then take into > account the d-cache, i-cache and TLB misses you incur on each switch, > and things go downhill very fast. The numbers given in the paper tell me otherwise. Let me give a few ballpark figures: Assume a context switch frequency of 1 kHz, and an execution rate of 1 billion instructions per seconds. This means that a process has 1 million instructions before the next context switch. Assuming that saving and restoring all that CPU state (registers, shadow registers, pipeline, caches, TLB contents) takes the equivalent of 1,000 instructions of RAM bandwidth, the performance hit is 0.1 percent - nothing that I'd worry much about. Of course, these figures are just inventions of mine; CPU state switching is probably around the order of magnitude that I have given, but I have no idea of a typical time slice length in a modern OS. OTOH it's probably safe to assume that the OS programmers have a good idea about the context switch overhead and will adjust time slice size so that the context switch overhead is small. In an Erlang context, things are yet a bit different. If every process does just a tiny bit of processing and goes into a wait long before it has used up its time slice, then process context switching becomes important. Again, I don't know how this works out for typical Erlang applications. > Of course, there are applications (like Mozilla!) that will just > consume all memory on your machine, and then some, so you better not > run multiple copies of them at once. :-) I don't know why I ever would want to run multiple copies of Mozilla ;-P But if you meant Apache: it's indeed running multiple OS processes. I don't think it's eating up much RAM that way - everything is in shared libraries, and the OS per-process overhead is small compared to the memory footprint of all that slice'n-dice functionality built into Apache. I'd really, really like to see how things work out on 2.6 when comparing Yaws and Apache - some factors favor Yaws, some favor Apache, and I simply don't know which of them weigh in more. >> The quoted IBM paper gave numbers for a concrete test run: a server >> with 9 GB of RAM and eight 700-MHz processors had a near-100% CPU >> usage, but just 36% memory usage (when serving 623 pages per >> second). More interesting is that server performance increased by a >> factor of six (!). Given that Yaws performance was ahead of Apache >> by a factor of roughly 2.5 (at least on the benchmarks posted by >> Joe), it would be very interesting to see how much Yaws profits >> from the new Linux kernel. > > Well, given that erts is bound to a single processor, you would need > to create a cluster of erts nodes, all running yaws, with some type > of load balancing front end. AFAIK there's already a load balancing package for web services, written in Erlang. (Sorry I forgot the name...) It would be interesting to see how things work out on a uniprocessor machine though. It's a strong selling point if you can say "you don't need an SMP machine for much higher loads if you use Yaws instead of Apache". Regards, Jo -- Currently looking for a new job. From vlad_dumitrescu@REDACTED Wed Feb 18 12:24:34 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 18 Feb 2004 12:24:34 +0100 Subject: Eclipse plugin advances Message-ID: Hi, I see there's not been any activity at the erlide.sf.net project for quite a while. I took the JavaEditor example plugin and am working my way through making it handle Erlang - so far syntax highlighting works 60% and it also has some other useless features. I think it would be a good idea not to sit on the code, and let others contribute too. :-) For this, I'd need to become a developer - Eric or Marc, could you arrange for that? My user id is 8024, login name 'vladdu'. Thanks in advance, Vlad From jozsef.berces@REDACTED Wed Feb 18 13:23:39 2004 From: jozsef.berces@REDACTED (Jozsef Berces (PR/ECZ)) Date: Wed, 18 Feb 2004 13:23:39 +0100 Subject: native/hipe questions Message-ID: I have some troubles with hipe. Under Solaris with OTP R9C, if I try to use a module compiled with native it does not work, I get the following error message: ** exited: {{badmatch,{["TO UPLTD WITH"],1}},[{convert,smartconcat,2}]} ** It seems that the fault is coming during lists:mapfoldl execution. Without the native code it works fine. I tried to compile it without optimization (with {hipe,o0}) but it did not help. Any suggestions? The other question is that how to remove the abstract code if the beam has been compiled with native? If I compile native it includes the abstract code as well. If I strip it then the native code is removed too. So it seems that native and abstract go together... Is there any solution? Thanks in advance, Jozsef This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kostis@REDACTED Wed Feb 18 13:38:22 2004 From: kostis@REDACTED (Kostis Sagonas) Date: Wed, 18 Feb 2004 13:38:22 +0100 (MET) Subject: native/hipe questions In-Reply-To: Mail from '"Jozsef Berces (PR/ECZ)" ' dated: Wed, 18 Feb 2004 13:23:39 +0100 Message-ID: <200402181238.i1ICcM4x018069@hamberg.it.uu.se> > I have some troubles with hipe. Under Solaris with OTP R9C, if I try > to use a module compiled with native it does not work. > ... > Any suggestions? Send to hipe@REDACTED a bug report with (a preferably minimized) file that shows the problem -- and directions on how to reproduce it. > The other question is that how to remove the abstract code if the > beam has been compiled with native? > If I compile native it includes the abstract code as well. Currently, .beam files contain both BEAM code and (possibly) native code. Part of the reason is for portability of .beam files. When the .beam file is loaded, if it contains native code and you are running in a HiPE-enabled system, then the native code is the one only loaded.(*) If you are running on a Erlang/OTP system without HiPE support (e.g. on PowerPC), the BEAM code is loaded instead. Kostis. (*) The BEAM code is still needed to convince the BEAM loader to do some of its magic -- e.g., generate code for module_info/[0,1] and other stuff like that. From enewhuis@REDACTED Wed Feb 18 15:45:07 2004 From: enewhuis@REDACTED (Eric Newhuis) Date: Wed, 18 Feb 2004 08:45:07 -0600 Subject: Eclipse plugin advances In-Reply-To: References: Message-ID: <0B817408-6221-11D8-AB0B-000A95D9A520@futuresource.com> I'd like to throw in my opinion that I think this is a project that should really be pushed. Really, if I could do Java and Erlang from the same environment I'd have more excuses to continue to use Erlang. On Feb 18, 2004, at 5:24 AM, Vlad Dumitrescu wrote: > Hi, > > I see there's not been any activity at the erlide.sf.net project for > quite a > while. > > I took the JavaEditor example plugin and am working my way through > making it > handle Erlang - so far syntax highlighting works 60% and it also has > some other > useless features. > > I think it would be a good idea not to sit on the code, and let others > contribute too. :-) > > For this, I'd need to become a developer - Eric or Marc, could you > arrange for > that? My user id is 8024, login name 'vladdu'. > > Thanks in advance, > Vlad > From vlad_dumitrescu@REDACTED Wed Feb 18 15:48:56 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 18 Feb 2004 15:48:56 +0100 Subject: Eclipse plugin advances References: <0B817408-6221-11D8-AB0B-000A95D9A520@futuresource.com> Message-ID: ----- Original Message ----- From: "Eric Newhuis" > I'd like to throw in my opinion that I think this is a project that > should really be pushed. Really, if I could do Java and Erlang from > the same environment I'd have more excuses to continue to use Erlang. This is more or less the reason I got to start with it. Of course, we can work with both Java and Erlang when using Emacs too, but if Emacs is not used in the organization, then it's not that easy :-) What's nice is that Eclipse plugins are quite modular, and it's easy to incrementally improve a plugin. /Vlad From vances@REDACTED Wed Feb 18 16:14:05 2004 From: vances@REDACTED (Vance Shipley) Date: Wed, 18 Feb 2004 10:14:05 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <40334941.6070001@web.de> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <40334941.6070001@web.de> Message-ID: <20040218151405.GA27269@frogman.motivity.ca> On Wed, Feb 18, 2004 at 12:15:13PM +0100, Joachim Durchholz wrote: } } AFAIK there's already a load balancing package for web services, written } in Erlang. (Sorry I forgot the name...) Eddie: http://eddie.sourceforge.net/ From joachim.durchholz@REDACTED Wed Feb 18 17:54:13 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Wed, 18 Feb 2004 17:54:13 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040218151405.GA27269@frogman.motivity.ca> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <40334941.6070001@web.de> <20040218151405.GA27269@frogman.motivi Message-ID: <403398B5.80809@web.de> Vance Shipley wrote: > On Wed, Feb 18, 2004 at 12:15:13PM +0100, Joachim Durchholz wrote: > } > } AFAIK there's already a load balancing package for web services, written > } in Erlang. (Sorry I forgot the name...) > > Eddie: http://eddie.sourceforge.net/ Even seems to be active too - there's a changelog entry that relates to making it run on R9B. Not sure why it isn't advertised more... anyway, it should scale Yaws to multiple machines with little effort. (Doesn't seem to help with utilizing multi-processor machines though... that seems to be something that should be done at the VM level.) Regards, Jo -- Currently looking for a new job. From jozsef.berces@REDACTED Wed Feb 18 01:53:06 2004 From: jozsef.berces@REDACTED (Jozsef Berces (PR/ECZ)) Date: Wed, 18 Feb 2004 01:53:06 +0100 Subject: native without abstract? Message-ID: How to remove the abstract code if the beam has been compiled with native? I am using R9C under Solaris and if I compile native it includes the abstract code as well. If I strip it then the native code is removed too. So it seems that native and abstract go together... Is there any solution? Thanks in advance, Jozsef This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mickael.remond@REDACTED Wed Feb 18 18:39:58 2004 From: mickael.remond@REDACTED (Mickael Remond) Date: Wed, 18 Feb 2004 18:39:58 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <403398B5.80809@web.de> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <40334941.6070001@web.de> <403398B5.80809@web.de> Message-ID: <20040218173957.GA6848@cgey.com> * Joachim Durchholz [2004-02-18 17:54:13 +0100]: > Vance Shipley wrote: > > >On Wed, Feb 18, 2004 at 12:15:13PM +0100, Joachim Durchholz wrote: > >} > >} AFAIK there's already a load balancing package for web services, written > >} in Erlang. (Sorry I forgot the name...) > > > >Eddie: http://eddie.sourceforge.net/ > > Even seems to be active too - there's a changelog entry that relates to > making it run on R9B. I have been maintaining it and did the modification for Erlang R9B. I was planning to do the same for R9C. > Not sure why it isn't advertised more... The code is big and sometime comment in swedish ;-) and the original team does not work on it anymore. > anyway, it should scale Yaws to multiple machines with little effort. > (Doesn't seem to help with utilizing multi-processor machines > though... that seems to be something that should be done at the VM > level.) I think, for Yaws, maybe a more straightforward approach would be better. Eddieware was essentially made for web scale load balancing (global scale). It make the assumption that machine are not all running on the same LAN. The load balancing schema is mostly DNS based. For more classical, LAN cluster load balancing other approach could be valid. However, I think Eddieware is still interesting (It does acceptation control to prevent user from accessing the cluster if resource are insufisant to ensure proper response time for already logged user; load balancing can be based on real server load, ...) If there is interest in Eddieware, we could discuss together how to make it revive. I have already been asked for bind9 support instead of Bind4. Please, if there is interest in it, ask now :-) -- Micka?l R?mond http://www.erlang-projects.org/ From richardc@REDACTED Wed Feb 18 18:57:35 2004 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 18 Feb 2004 18:57:35 +0100 (MET) Subject: native without abstract? In-Reply-To: References: Message-ID: On Wed, 18 Feb 2004, Jozsef Berces (PR/ECZ) wrote: > How to remove the abstract code if the beam has been compiled with native? It seems that the problem is that the strip function in beam_lib does not know about native-code chunks - and it simply removes everything that it does not know about (which includes the abstract code). This is something that needs to be fixed in some way, so thanks for reporting it. > I am using R9C under Solaris and if I compile native it includes the > abstract code as well. If I strip it then the native code is removed > too. So it seems that native and abstract go together... > > Is there any solution? Compile your modules with the 'native' flag, but do not use the 'debug_info' flag. Then you will not get the abstract code. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From enano@REDACTED Wed Feb 18 19:48:00 2004 From: enano@REDACTED (Miguel Barreiro) Date: Wed, 18 Feb 2004 19:48:00 +0100 (CET) Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040218005149.GB22613@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: > One reason Erlang runs so well (and any other very tight user space > implementation) is they can eliminate all of the memory overheads, making an > entire process fit into just a cache line or two in the processor's data cache. > When an entire Erlang process can get swapped in by just one or two memory > loads, and has no TLB miss penalties, etc, life can be very, very good. On the other hand, the beam runtime is amazingly fast on processors with a large cache. I'm trying to gather some benchmark data on such systems, and will report. From cpressey@REDACTED Wed Feb 18 19:55:59 2004 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 18 Feb 2004 10:55:59 -0800 Subject: So now all I'd like in Erlang is... In-Reply-To: <20040218005825.GC22613@spearce.org> References: <20040218005825.GC22613@spearce.org> Message-ID: <20040218105559.018ea49a.cpressey@catseye.mine.nu> On Tue, 17 Feb 2004 19:58:25 -0500 Shawn Pearce wrote: > I've often wondered why Erlang code is: > > foo(X) -> > ok. > > and not: > > Foo = fun(X) -> > ok > end. > > with call sites using: > > Foo(x). > > instead of: > > foo(x). > > In other words, why are named functions different from lambdas? Why > not make all named functions actually global variables which are > assigned to a lambda when the module loads? How would that work w.r.t. dynamic code reloading? -Chris From mlogan@REDACTED Wed Feb 18 20:42:41 2004 From: mlogan@REDACTED (Martin J. Logan) Date: 18 Feb 2004 13:42:41 -0600 Subject: Read terms from the command line (answer) In-Reply-To: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> References: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> Message-ID: <1077133360.27748.2391.camel@dhcp-lom-194-186.futuresource.com> I guess that I will answer my own question FYI. The way to convert strings to terms is in the following manner. This is well documented by the way:( shame on me. The first thing to do is {ok, Toks, Line} = erl_scan:string("[[logan], {martin}]. ", 1). The term should end in a "." followed by whitespace. erl_parse:parse_term(Toks). This returns {ok,[[logan],{martin}]} beautiful... Cheers, Martin On Tue, 2004-02-17 at 12:58, Martin J. Logan wrote: > Anyone know how to read erlang terms off the command line. Specifically > I would like to call an erlang function via erl -s or something similar > and pass the function terms. Does anyone know of a method to "consult" > chars passed in from the command line. > > > Martin From sam@REDACTED Wed Feb 18 20:55:51 2004 From: sam@REDACTED (Samuel Tardieu) Date: Wed, 18 Feb 2004 20:55:51 +0100 Subject: Mnesia, disconnections and reconnections Message-ID: <87hdxop3g8.fsf@beeblebrox.enst.fr> Hi. I have implemented a greylist filter[1] for Postfix in Erlang using Mnesia in order to check whether this efficiently reduces spam or not. As the system works best if all the MXs use the same database, I use a distributed Mnesia database with all nodes having disc_copies of every table (3 nodes). However, the nodes sometime get disconnected from each other because of network outages. As the node don't restart (they weren't shutdown), they all use different versions of the tables. How can I designate one of the nodes to be the master one so that in case of a reconnection the content of the tables will be reloaded from this node? Or is there a better way to do this? Sam Notes: [1] http://www.greylisting.org/ -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From sam@REDACTED Wed Feb 18 20:57:23 2004 From: sam@REDACTED (Samuel Tardieu) Date: Wed, 18 Feb 2004 20:57:23 +0100 Subject: epmd, Erlang nodes and IPv6 Message-ID: <87d68cp3do.fsf@beeblebrox.enst.fr> Is there a way to have Erlang nodes use IPv6 between each other? Is there a way to have epmd listen on both IPv4 and IPv6 addresses? Sam -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From ulf.wiger@REDACTED Wed Feb 18 22:33:34 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Wed, 18 Feb 2004 22:33:34 +0100 Subject: Read terms from the command line In-Reply-To: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> References: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> Message-ID: On 17 Feb 2004 12:58:08 -0600, Martin J. Logan wrote: > Anyone know how to read erlang terms off the command line. Specifically > I would like to call an erlang function via erl -s or something similar > and pass the function terms. Does anyone know of a method to "consult" > chars passed in from the command line. You can use init:get_arguments() to inspect the command line. To get erlangs terms, you'll have to do some parsing. If you use -s, the function will get the arguments as a list of strings. erl_scan:string/1 and erl_parse:parse_term/1 can be used to convert to erlang terms, if necessary. /Uffe -- Ulf Wiger From sean.hinde@REDACTED Thu Feb 19 00:55:52 2004 From: sean.hinde@REDACTED (Sean Hinde) Date: Thu, 19 Feb 2004 00:55:52 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040218005149.GB22613@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: On 18 Feb 2004, at 01:51, Shawn Pearce wrote: > > Well, given that erts is bound to a single processor, you would need to > create a cluster of erts nodes, all running yaws, with some type of > load > balancing front end. This is one area Apache really shines in, as it > easily allows this to be setup: because Apache is multi-process > already, it > can easily share the single TCP server socket with all of its siblings > and > decide who gets the next request. > > Does anyone think it might be possible to modify gen_tcp in such a way > that > we could use multiple nodes on the same system all bound to the same > TCP port, > and using some sort of accept lock between them? I'd think this could > be done > something like this: This method was suggested to me earlier today in a completely different context but using UDP sockets. A strange co-incidence indeed. For UDP sockets the documentation would seem to suggest an existing mechanism using the option: "{fd,Fd} If a UDP socket has somehow been opened without using gen_udp, use this option to pass in the file descriptor for it and create a Socket for it." But just getting the FD (using inet:getfd(Socket). ) and trying this in another Erlang node with gen_udp:fdopen(FD, []) doesn't work (probably obvious in hindsight). The usage described to me earlier today is that 1 UNIX process opens the socket and then forks additional child processes which get access to the file descriptor. I guess that UNIX treats child processes in a special way (allows them to receive data on another processes FD). Anyway. If it is possible this would be a VERY attractive way to take advantage of multiple CPU machines. Anyone? Sean From spearce@REDACTED Thu Feb 19 01:15:29 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 18 Feb 2004 19:15:29 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: <20040219001529.GA24157@spearce.org> I think Sean forgot to post this to the list, and replied directly to me... His "anyone?" comment at the end gives it away. :) When a process forks in UNIX to create a child, all file descriptors are automatically made available in the child. When the child uses an exec call to start a different program within that process, some file descriptors are automatically closed, and some remain open. This is controlled by the FD_CLOEXEC flag, set through fcntl(2). The idea here with gen_tcp would be to: - use a "node launcher" that creates the incoming UDP and TCP sockets - removes FD_CLOEXEC bit to make sure the fd stays open - forks a process for each node - execs erlang - use gen_tcp and gen_udp's {fd, F} options to get 'real' sockets in erlang. - create new driver calls to allow adding and removing that fd from the set of FDs being monitored by the erts event loop. The reason the last is important is that some OSes may tell multiple nodes there is data ready, but only one UDP packet has actually come in. If the socket is in blocking mode, the other nodes will wake up, enter the driver, and block trying to read the UDP packet, while one node will get the packet. Clearly not good. Some UNIX variants have a "feature" (bug) where it wakes up multiple processes, telling them a UDP packet or new TCP connection is available. The processes come out of select/poll, hit read/accept and more than one of them gets the same TCP socket or the same UDP packet. Now you have more than one node attempting to process the data, and you may generate two different replies when only one was necessary. I guess you could try to have the Erlang nodes elect who will handle the connection/packet that just arrived, but there is no way for them to know if they have duplicates or not. So life could get ugly. But if the gen_tcp/udp drivers support dynamically enabling disabling the server socket from the erts event loop, life is ok. This would work very well on a multiple CPU machine, as each CPU can have its own dedicated node, epmd+normal erlang monitoring can be used to know state of the other nodes, and life is very sweet. So how about it? :-) Sean Hinde wrote: > On 18 Feb 2004, at 01:51, Shawn Pearce wrote: > >Well, given that erts is bound to a single processor, you would need to > >create a cluster of erts nodes, all running yaws, with some type of > >load > >balancing front end. This is one area Apache really shines in, as it > >easily allows this to be setup: because Apache is multi-process > >already, it > >can easily share the single TCP server socket with all of its siblings > >and > >decide who gets the next request. > > > >Does anyone think it might be possible to modify gen_tcp in such a way > >that > >we could use multiple nodes on the same system all bound to the same > >TCP port, > >and using some sort of accept lock between them? I'd think this could > >be done > >something like this: > > This method was suggested to me earlier today in a completely different > context but using UDP sockets. A strange co-incidence indeed. > > For UDP sockets the documentation would seem to suggest an existing > mechanism using the option: > > "{fd,Fd} > If a UDP socket has somehow been opened without using gen_udp, use > this option to pass in the file descriptor for it and create a Socket > for it." > > But just getting the FD (using inet:getfd(Socket). ) and trying this in > another Erlang node with gen_udp:fdopen(FD, []) doesn't work (probably > obvious in hindsight). > > The usage described to me earlier today is that 1 UNIX process opens > the socket and then forks additional child processes which get access > to the file descriptor. I guess that UNIX treats child processes in a > special way (allows them to receive data on another processes FD). > > Anyway. If it is possible this would be a VERY attractive way to take > advantage of multiple CPU machines. > > Anyone? > > Sean -- Shawn. From spearce@REDACTED Thu Feb 19 01:27:03 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 18 Feb 2004 19:27:03 -0500 Subject: So now all I'd like in Erlang is... In-Reply-To: <20040218105559.018ea49a.cpressey@catseye.mine.nu> References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> Message-ID: <20040219002703.GB24157@spearce.org> Chris Pressey wrote: > On Tue, 17 Feb 2004 19:58:25 -0500 > Shawn Pearce wrote: > > > I've often wondered why Erlang code is: > > > > foo(X) -> > > ok. > > > > and not: > > > > Foo = fun(X) -> > > ok > > end. > > > > with call sites using: > > > > Foo(x). > > > > instead of: > > > > foo(x). > > > > In other words, why are named functions different from lambdas? Why > > not make all named functions actually global variables which are > > assigned to a lambda when the module loads? > > How would that work w.r.t. dynamic code reloading? I think it would work just like it does now. The only difference is that when a module is loaded, rather than registering its exported functions in a table, a module is actually executed. Thus modules are more like this (once the compiler gets done with them): fun() -> code:register_module(my_module), SomeConstant = "this is a constant string", code:register_module_function(my_module, foo, fun(X) -> SomeConstant ++ " " ++ atom_to_list(X) end) end. Or something. :) The code server basically runs the module when it loads it, allowing the other funs in that module to get put into the symbol table, and the constants to be created. So external calls would still resolve like they do now, its just that the symbol table used to resolve them is built of funs rather than functions, which are more or less like named funs, but without environment tagging along. Since Erlang is single assignment, the environment is ok to have, its just constants which you want to resolve at runtime. Each time the module loads, the constants are reconstructed and stored in the environments. This might be very tough to do in implementation with the private heap BEAM, because there is no global data... I can think of uses like: PrivDir = code:priv_dir(gen_serial), open = fun(Name) -> open_port({spawn, PrivDir ++ "/bin/serial_esock.exe"} ...) end. Would be nice to do. Today we do: open(Name) -> open_port({spawn, priv_dir() ++ "/bin/serial_esock.exe"} ...). priv_dir() -> code:priv_dir(gen_serial). Not very different at all, and equally easy to write. Just the runtime implications are a little different (in more ways than just performance). But from a semantic consistentancy point of view, I just gotta ask the question of why are functions different from funs? :-) -- Shawn. Delay is preferable to error. -- Thomas Jefferson From sean.hinde@REDACTED Thu Feb 19 01:44:06 2004 From: sean.hinde@REDACTED (Sean Hinde) Date: Thu, 19 Feb 2004 01:44:06 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040219001529.GA24157@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <20040219001529.GA24157@spearce.org> Message-ID: On 19 Feb 2004, at 01:15, Shawn Pearce wrote: << Lots of nice answer to study, thank you. >> I just carried on reading about such issues, and it seems that the dup system call might offer some assistance with setting this whole thing up. I don't really get how you are supposed to pass on the new file descriptor to another process though, and the descriptions I have read (e.g. http://nscp.upenn.edu/aix4.3html/aixprggd/genprogc/fdescript.htm ) are a little hard for an Erlang only sort of guy to comprehend.. More reading. > So how about it? :-) Yes please indeed. Sean From sean.hinde@REDACTED Thu Feb 19 01:55:45 2004 From: sean.hinde@REDACTED (Sean Hinde) Date: Thu, 19 Feb 2004 00:55:45 +0000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <20040219001529.GA24157@spearce.org> Message-ID: <595C8D1E-6276-11D8-9134-000A95927CCE@mac.com> On 19 Feb 2004, at 00:44, Sean Hinde wrote: > > On 19 Feb 2004, at 01:15, Shawn Pearce wrote: > > << Lots of nice answer to study, thank you. >> > > I just carried on reading about such issues, and it seems that the dup > system call might offer some assistance with setting this whole thing > up. I don't really get how you are supposed to pass on the new file > descriptor to another process though, and the descriptions I have read > (e.g. http://nscp.upenn.edu/aix4.3html/aixprggd/genprogc/fdescript.htm > ) are a little hard for an Erlang only sort of guy to comprehend.. > > More reading. OK, I see. It truly is a fork only thing. Sean From marc.vanwoerkom@REDACTED Thu Feb 19 02:18:12 2004 From: marc.vanwoerkom@REDACTED (Marc van Woerkom) Date: Thu, 19 Feb 2004 02:18:12 +0100 Subject: Eclipse plugin advances In-Reply-To: References: Message-ID: > I see there's not been any activity at the erlide.sf.net project for > quite a while. It is not lack of interest! Eclipse is the first development environment since Emacs that I like very much. I think it is one very good way to realize a modern graphical style Erlang IDE. My reasons for slow progress are a) Eclipse is huge I still do not understand its architecture well enough and if there is a specific way how a good eclipse IDE for a language should get implement. What is there as open source is the JDT or J2SE development and that CDT for C++ development, I still hope to learn from those. Since November I am grinding through some books that teach eclipse internals and especially plugin development - Gamma/Beck: Contributing through eclipse - Shavor et al: eclipse (great intro on use, also plugin dev) - Budinsky et al: eclipse modeling frame work (e.g. code generation support) b) economic pressure I lost my developer job last May, a position where I had to compete already with 200 other candidates. The economy here in Germany seems recovering slightly, but it had no effect on the job market yet and in a very typical German way they insist on a finished degree now. Thus 6+ years work experience aren't enough anymore to get a job (but just a degree without 2+ years is not enough too). That's why I am focussing to finish a degree as fast as possible, and it seems I can do that this autumn. So my free time is not as much as it used to be. :) BTW one of my exams was on real time systems, where I learned a bit of PEARL (not perl) which is different from Erlang but also another industrial way to handle similiar topics. c) Erlang is huge as well But that depresses me a lot less than a) and b) > I took the JavaEditor example plugin and am working my way through > making it handle Erlang - so far syntax highlighting works 60% and it > also has some other useless features. I feel guilty to strive for a great solution, which has the danger of not materializing. But I have nothing against just starting with something and improving that if possible. I hope Eric sees this the same wy. > I think it would be a good idea not to sit on the code, and let others > contribute too. :-) Yes. > For this, I'd need to become a developer - Eric or Marc, could you > arrange for > that? My user id is 8024, login name 'vladdu'. I do that in a moment. Regards, Marc From fritchie@REDACTED Thu Feb 19 03:41:03 2004 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Wed, 18 Feb 2004 20:41:03 -0600 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: Message of "Thu, 19 Feb 2004 01:44:06 +0100." Message-ID: <200402190241.i1J2f352029750@snookles.snookles.com> >>>>> "sh" == Sean Hinde writes: sh> I just carried on reading about such issues, and it seems that the sh> dup system call might offer some assistance with setting this sh> whole thing up. I don't really get how you are supposed to pass on sh> the new file descriptor to another process though, and the sh> descriptions I have read sh> (e.g. http://nscp.upenn.edu/aix4.3html/aixprggd/genprogc/fdescript.htm sh> ) are a little hard for an Erlang only sort of guy to comprehend.. The king of all references on the subject is (IMHO) W. Richard Steven's _UNIX Network Programming_. Unless you consider it to be the more updated W. Richard Steven's _Advanced Programming in the Unix Environment_, which is a bit newer. I just tore our house upside-down looking for _APUE_, but I couldn't find it, which makes me sad, because good reference books like _APUE_ should always be within easy reach. As a consolation prize, I found a description of the System V-style file descriptor passing in _UNIX System V Network Programming_ by Stephen A. Rago. Steven's books describe both the System V-style and BSD-style techniques. The source code to all of the examples in those two Steven's books can be found at ftp://ftp.uu.net/published/books/. System V-style: Both sides open a pipe. The sending process uses an ioctl(2) call to pass the descriptor across the pipe. The receiving process uses ioctl(2) to get the descriptor. BSD-style: Both sides open a UNIX domain socket (pipe OK too?). The sending process formats a magic "struct msghdr" structure, then sends it using sendmsg(2) across the UNIX domain socket. The receiving process uses recvmsg(2) creates a similar structure and uses recvmsg(2) to get the descriptor. -Scott From andrae.muys@REDACTED Thu Feb 19 03:53:24 2004 From: andrae.muys@REDACTED (Andrae Muys) Date: Thu, 19 Feb 2004 12:53:24 +1000 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040219001529.GA24157@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> <20040219001529.GA24157@spearce.org> Message-ID: <40342524.8090503@braintree.com.au> Shawn Pearce wrote: > Some UNIX variants have a "feature" (bug) where it wakes up multiple > processes, telling them a UDP packet or new TCP connection is available. > The processes come out of select/poll, hit read/accept and more than > one of them gets the same TCP socket or the same UDP packet. Now you > have more than one node attempting to process the data, and you may > generate two different replies when only one was necessary. > > I guess you could try to have the Erlang nodes elect who will handle > the connection/packet that just arrived, but there is no way for > them to know if they have duplicates or not. So life could get > ugly. But if the gen_tcp/udp drivers support dynamically enabling > disabling the server socket from the erts event loop, life is ok. > Not entirely correct. The semantics of accept() guarentee only one return across the multiple children. The 'wake-one' semantics offered by various unixen is strictly an optimisation to avoid the cache/process thrashing involved when multiple children wake up in response to a connection and then all-but-one immediately wait-on-accept. So there is no chance of duplicates, or multiple replies. Only one node will actually recieve the connection. Note that for UDP you don't call accept, you generally call recv, or recvfrom. However I believe the semantics regarding simulataneous calls are similar. > This would work very well on a multiple CPU machine, as each CPU > can have its own dedicated node, epmd+normal erlang monitoring can > be used to know state of the other nodes, and life is very sweet. > > So how about it? :-) Andrae -- Andrae Muys Engineer Braintree Communications "Now, allowing captured continuations to be inspected and altered at runtime (including binding mutation, complete rebinding of scopes, and call tree mutation)... *that* is really evil. And, I should point out, quite useful." - Dan Sugalski From marc.vanwoerkom@REDACTED Thu Feb 19 04:04:13 2004 From: marc.vanwoerkom@REDACTED (Marc van Woerkom) Date: Thu, 19 Feb 2004 04:04:13 +0100 Subject: Fwd: Re: Eclipse plugin advances In-Reply-To: References: <0B817408-6221-11D8-AB0B-000A95D9A520@futuresource.com> Message-ID: On Wed, 18 Feb 2004 08:45:07 -0600, Eric Newhuis wrote: > I'd like to throw in my opinion that I think this is a project that > should really be pushed. Really, if I could do Java and Erlang from the > same environment I'd have more excuses to continue to use Erlang. My personal main wish would be to make learning and understanding Erlang better. Getting code assist working, viewing nice layouted documentation without leaving the ide, incremental search stuff.. At some point easy debugging, easy dealing with mnesia and distribution, finite state machines and such. Perhaps some visual editor for some useful graphical toolkit (ex11?). One distant day adopting of some useful graphical design scheme (some UML equivalent for concurrent and functional programming) Integrating yaws and all the xml stuff for creating web apps in a sane way.. Thus many of the stuff you can do with a modern J2SE or J2EE ide (remember that IBM builds a very impressive J2EE IDE called websphere studio or on top of eclipse) That is enough fun for years to come! Regards, Marc From ok@REDACTED Thu Feb 19 04:50:40 2004 From: ok@REDACTED (Richard A. O'Keefe) Date: Thu, 19 Feb 2004 16:50:40 +1300 (NZDT) Subject: Advantages of a large number of threads cf other approaches? Message-ID: <200402190350.i1J3oeqI169661@atlas.otago.ac.nz> I wrote: > Did I mention that Smalltalk-80 has TWO key features? OO is one, and > (simulated) concurrency is the other. Joachim Durchholz replied: That would be interesting news to me - where is the concurrency in Smalltalk-80? Fire up your copy of Squeak, open a Browser, and in the Class Category pane in the top left corner you will see the class category "Kernel-Processes". Click on that, and in the Class pane (second pane in the top row) you will see Delay EventSensor InputSensor Process ProcessorScheduler Semaphore The classes Process, ProcessorScheduler, Semaphore, and Delay (at least) are described in the classic Smalltalk-80 books by Goldberg et al. (There is only one ProcessorScheduler instance; it's called Processor). For example, to create a new process, do [some message send that starts something interesting] forkAt: Processor userBackgroundPriority I suspect that this stuff goes back to Smalltalk-78 or before. (Oh, you don't have Squeak to check this out? It's free. www.squeak.org) From marc.vanwoerkom@REDACTED Thu Feb 19 05:52:20 2004 From: marc.vanwoerkom@REDACTED (Marc van Woerkom) Date: Thu, 19 Feb 2004 05:52:20 +0100 Subject: Eclipse plugin advances In-Reply-To: References: <0B817408-6221-11D8-AB0B-000A95D9A520@futuresource.com> Message-ID: On Wed, 18 Feb 2004 08:45:07 -0600, Eric Newhuis wrote: > I'd like to throw in my opinion that I think this is a project that > should really be pushed. Really, if I could do Java and Erlang from the > same environment I'd have more excuses to continue to use Erlang. My personal main wish would be to make learning and understanding Erlang better. Getting code assist working, viewing nice layouted documentation without leaving the IDE, incremental search stuff.. At some point easy debugging, easy dealing with mnesia and distribution, finite state machines and such. Perhaps some visual editor for some useful graphical toolkit (ex11?). One distant day adopting of some useful graphical design scheme (some UML equivalent for concurrent and functional programming) Integrating yaws and all the xml stuff for creating web apps in a sane way.. Thus many of the stuff you can do with a modern J2SE or J2EE ide (remember that IBM builds a very impressive J2EE IDE called websphere studio or on top of eclipse) That is enough fun for years to come! Regards, Marc From vances@REDACTED Thu Feb 19 06:01:03 2004 From: vances@REDACTED (Vance Shipley) Date: Thu, 19 Feb 2004 00:01:03 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <200402190241.i1J2f352029750@snookles.snookles.com> References: <200402190241.i1J2f352029750@snookles.snookles.com> Message-ID: <20040219050103.GC28300@frogman.motivity.ca> You can to this list: Solaris-style: doors On Wed, Feb 18, 2004 at 08:41:03PM -0600, Scott Lystig Fritchie wrote: } } System V-style: } Both sides open a pipe. } The sending process uses an ioctl(2) call to pass the } descriptor across the pipe. } The receiving process uses ioctl(2) to get the descriptor. } } BSD-style: } Both sides open a UNIX domain socket (pipe OK too?). } The sending process formats a magic "struct msghdr" structure, } then sends it using sendmsg(2) across the UNIX domain socket. } The receiving process uses recvmsg(2) creates a similar } structure and uses recvmsg(2) to get the descriptor. } } -Scott From spearce@REDACTED Thu Feb 19 07:17:55 2004 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 19 Feb 2004 01:17:55 -0500 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040219050103.GC28300@frogman.motivity.ca> References: <200402190241.i1J2f352029750@snookles.snookles.com> <20040219050103.GC28300@frogman.motivity.ca> Message-ID: <20040219061755.GC24157@spearce.org> Here's the problem: that's at least 3 different methods! Can we say "#ifdef" ? :-) Vance Shipley wrote: > > You can to this list: > > Solaris-style: doors > > > On Wed, Feb 18, 2004 at 08:41:03PM -0600, Scott Lystig Fritchie wrote: > } > } System V-style: > } Both sides open a pipe. > } The sending process uses an ioctl(2) call to pass the > } descriptor across the pipe. > } The receiving process uses ioctl(2) to get the descriptor. > } > } BSD-style: > } Both sides open a UNIX domain socket (pipe OK too?). > } The sending process formats a magic "struct msghdr" structure, > } then sends it using sendmsg(2) across the UNIX domain socket. > } The receiving process uses recvmsg(2) creates a similar > } structure and uses recvmsg(2) to get the descriptor. > } > } -Scott -- Shawn. QOTD: "Do you smell something burning or is it me?" -- Joan of Arc From vlad_dumitrescu@REDACTED Thu Feb 19 08:31:52 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 19 Feb 2004 08:31:52 +0100 Subject: Eclipse plugin advances References: Message-ID: From: "Marc van Woerkom" > > I see there's not been any activity at the erlide.sf.net project for > > quite a while. > > It is not lack of interest! I didn't say it is ! :-) > a) Eclipse is huge True. In my experience, in such cases it is easier to start small and build on incrementally. The Eclipse model lets one do that very nicely. Should the architecture become messed up, it's also easy to start over. > b) economic pressure Sorry to hear that! I'll try to import the code I have to sourceforge. best regards, Vlad From dgud@REDACTED Thu Feb 19 09:20:26 2004 From: dgud@REDACTED (Dan Gudmundsson) Date: Thu, 19 Feb 2004 09:20:26 +0100 Subject: Mnesia, disconnections and reconnections In-Reply-To: <87hdxop3g8.fsf@beeblebrox.enst.fr> References: <87hdxop3g8.fsf@beeblebrox.enst.fr> Message-ID: <16436.29130.121328.160111@rian.du.uab.ericsson.se> See mnesia:set_master_nodes/[12] However you should reset it to the empty list after re-starting mnesia. It's usually best to reset it with empty list after starting mnesia. /Dan Samuel Tardieu writes: > Hi. > > I have implemented a greylist filter[1] for Postfix in Erlang using > Mnesia in order to check whether this efficiently reduces spam or > not. As the system works best if all the MXs use the same database, I > use a distributed Mnesia database with all nodes having disc_copies of > every table (3 nodes). > > However, the nodes sometime get disconnected from each other because > of network outages. As the node don't restart (they weren't shutdown), > they all use different versions of the tables. > > How can I designate one of the nodes to be the master one so that in > case of a reconnection the content of the tables will be reloaded from > this node? Or is there a better way to do this? > > Sam > > Notes: > [1] http://www.greylisting.org/ > -- > Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From hakan@REDACTED Thu Feb 19 09:34:09 2004 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 19 Feb 2004 09:34:09 +0100 (MET) Subject: Mnesia, disconnections and reconnections In-Reply-To: <16436.29130.121328.160111@rian.du.uab.ericsson.se> Message-ID: On Thu, 19 Feb 2004, Dan Gudmundsson wrote: Danne> See mnesia:set_master_nodes/[12] Danne> Danne> However you should reset it to the empty list after re-starting Danne> mnesia. It's usually best to reset it with empty list after starting Danne> mnesia. You need to be careful here, as you need to wait for all involved tables to actually be loaded from the master node(s) before you safely can empty the master node list. Use mnesia:wait_for_tables/2 for this purpose. /H?kan --- H?kan Mattsson Ericsson High Availability Software, DBMS Internals http://www.erlang.org/~hakan/ This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From bengt.kleberg@REDACTED Thu Feb 19 10:09:57 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 19 Feb 2004 10:09:57 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <200402190241.i1J2f352029750@snookles.snookles.com> References: <200402190241.i1J2f352029750@snookles.snookles.com> Message-ID: <40347D65.6080900@ericsson.com> Scott Lystig Fritchie wrote: > ...deleted > >The king of all references on the subject is (IMHO) W. Richard >Steven's _UNIX Network Programming_. Unless you consider it to be the >more updated W. Richard Steven's _Advanced Programming in the Unix >Environment_, which is a bit newer. > >I just tore our house upside-down looking for _APUE_, but I couldn't >find it, which makes me sad, because good reference books like _APUE_ >should always be within easy reach. As a consolation prize, I found a >description of the System V-style file descriptor passing in _UNIX >System V Network Programming_ by Stephen A. Rago. Steven's books >describe both the System V-style and BSD-style techniques. > > > fwiw: Addison Wesley Professional might ''soon'' publish an new version of APUE, updated by mr rago. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From richardc@REDACTED Thu Feb 19 10:52:11 2004 From: richardc@REDACTED (Richard Carlsson) Date: Thu, 19 Feb 2004 10:52:11 +0100 (MET) Subject: Read terms from the command line In-Reply-To: References: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> Message-ID: Actually, 'erl -s ...' passes the arguments as atoms (which among other things limits their size to 255 characters). Use 'erl -run ...' to have them passed as strings. /Richard On Wed, 18 Feb 2004, Ulf Wiger wrote: > > Anyone know how to read erlang terms off the command line. Specifically > > I would like to call an erlang function via erl -s or something similar > > and pass the function terms. Does anyone know of a method to "consult" > > chars passed in from the command line. > > You can use init:get_arguments() to inspect the command line. > > To get erlangs terms, you'll have to do some parsing. > > If you use -s, the function will get the arguments as a list of > strings. > > erl_scan:string/1 and erl_parse:parse_term/1 can be used to > convert to erlang terms, if necessary. > > /Uffe > -- > Ulf Wiger > > Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From joachim.durchholz@REDACTED Thu Feb 19 11:51:05 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Thu, 19 Feb 2004 11:51:05 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <200402190350.i1J3oeqI169661@atlas.otago.ac.nz> References: <200402190350.i1J3oeqI169661@atlas.otago.ac.nz> Message-ID: <40349519.70005@web.de> Richard A. O'Keefe wrote: > I wrote: >> Did I mention that Smalltalk-80 has TWO key features? OO is one, >> and (simulated) concurrency is the other. > Joachim Durchholz replied: > That would be interesting news to me - where is the concurrency in > Smalltalk-80? > > Fire up your copy of Squeak, open a Browser, and in the Class > Category pane in the top left corner you will see the class category > "Kernel-Processes". Click on that, and in the Class pane (second > pane in the top row) you will see > Delay > EventSensor > InputSensor > Process > ProcessorScheduler > Semaphore Oh, right - but this process stuff isn't very central to Smalltalk-as-a-language (not in the way that concurrency is for Erlang, and also not suitable for the way concurrency is used in Erlang). IOW I think it's an accident that both Erlang and Smalltalk are great languages with concurrency. > (Oh, you don't have Squeak to check this out? It's free. www.squeak.org) I know, I used to have one :-) It's just been a few years since I last fired it up. Regards, Jo -- Currently looking for a new job. From ulf.wiger@REDACTED Thu Feb 19 11:55:25 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 19 Feb 2004 11:55:25 +0100 Subject: Mnesia, disconnections and reconnections In-Reply-To: References: Message-ID: On Thu, 19 Feb 2004 09:34:09 +0100 (MET), Hakan Mattsson wrote: > On Thu, 19 Feb 2004, Dan Gudmundsson wrote: > > Danne> See mnesia:set_master_nodes/[12] > Danne> > Danne> However you should reset it to the empty list after re-starting > Danne> mnesia. It's usually best to reset it with empty list after > starting > Danne> mnesia. > > You need to be careful here, as you need to wait for all involved > tables to actually be loaded from the master node(s) before you safely > can empty the master node list. Use mnesia:wait_for_tables/2 for this > purpose. > > /H?kan But of course, there are some tricky cases where the tables will never load, and if you want to be really safe, you need to handle those too. There is no generic algorithm that will work in all cases, so what you do to resolve different situations is dependent on your particular system. If i recall correctly, these situations might cause problems: 1) Node A dies, node B logs that; B dies; A restarts, but cannot load tables, since it doesn't know that they are the latest copy. 2) Communication lost, A and B both think they are master; comm. restored, but now you may have inconsistency in your tables. 3) Comm. lost, and is restored; A and B both detect that there may be inconsistency and restart to resolve it; A sets B to master; B sets A to master (I don't recall if this leads to a deadlock) 4) Same as 3), but both identify B as master; B dies before A has loaded all tables from B; A may now have only partially consistent data. (1) is difficult to detect. In AXD 301, we do a WFG analysis in a special program that monitors mnesia table loading; we also have the rule that a node may force-load tables if the other nodes are not there. (2) You can detect this either through mnesia's event mechanism, and you can opt to write your own mnesia event handler (see the mnesia docs). Another way to do this is to set -kernel dist_auto_connect once, and have a backdoor ping (e.g. on UDP). This means that the nodes will not reconnect automatically unless one of the nodes restarts first. If you get a UDP ping from a node that is not in the nodes() list, you have a partitioned network. The UDP ping could also carry enough info that you can decide which node should be the master, and which should restart. This also prevents (3) from happening. (4) I don't know how to solve this, and don't recall exactly what will happen. When using mnesia:wait_for_tables(Tabs, Timeout), setting the Timeout may be tricky, esp. if you may want your node to force_load tables if the other nodes stay down. Setting the timeout too short means that wait_for_tables may time out while tables are still loading. You will be told how many tables remain, and can write logic to check that things are moving (which they may not appear to be, if a huge table is being synched over a slow network.) Setting the timeout too long may mean that you get unnecessary downtime in your system. Hope I haven't scared you off now. ;) /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From bengt.kleberg@REDACTED Thu Feb 19 13:07:58 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 19 Feb 2004 13:07:58 +0100 Subject: Read terms from the command line In-Reply-To: References: <1077044288.27748.2206.camel@dhcp-lom-194-186.futuresource.com> Message-ID: <4034A71E.3020908@ericsson.com> Richard Carlsson wrote: >Actually, 'erl -s ...' passes the arguments as atoms (which among >other things limits their size to 255 characters). > > just to be really explicit: 'erl -s ...' passes passes the arguments as a list of atoms. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ake.ai.johansson@REDACTED Thu Feb 19 13:33:48 2004 From: ake.ai.johansson@REDACTED (=?iso-8859-1?Q?=C5ke_Ai_Johansson_=28LN/EAB=29?=) Date: Thu, 19 Feb 2004 13:33:48 +0100 Subject: Comparing number of lines of code Erlang <-> C Message-ID: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> Erlang is usually more compact regarding lines of code than for example C. Is there a factor that most people agree on? If there is: What is the factor and has it been verified in a real situation, for example when a system has been re-written? / ?ke This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From sam@REDACTED Thu Feb 19 14:19:04 2004 From: sam@REDACTED (Samuel Tardieu) Date: Thu, 19 Feb 2004 14:19:04 +0100 Subject: Mnesia, disconnections and reconnections References: Message-ID: <871xor2omv.fsf@beeblebrox.enst.fr> >>>>> "Ulf" == Ulf Wiger writes: > Hope I haven't scared you off now. ;) No, thanks a lot for your explanation, this is food for thoughts. Sam -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From bengt.kleberg@REDACTED Thu Feb 19 14:34:53 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 19 Feb 2004 14:34:53 +0100 Subject: Comparing number of lines of code Erlang <-> C In-Reply-To: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> References: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> Message-ID: <4034BB7D.80005@ericsson.com> ?ke Ai Johansson (LN/EAB) wrote: >Erlang is usually more compact regarding lines of code than for example C. > >Is there a factor that most people agree on? > > > i used to write c programs with ose (real time kernel). my prototypes i did in scheme on a unix machine. i had written an ose emulating library. the normal code line explosion when going to c was 10 times. and then i had to add more things needed for the target platform. while not a best fit to your problem i still belive there are enough similarities between erlang and scheme to warrant this email. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From mbj@REDACTED Thu Feb 19 14:59:24 2004 From: mbj@REDACTED (Martin Bjorklund) Date: Thu, 19 Feb 2004 14:59:24 +0100 (CET) Subject: Comparing number of lines of code Erlang <-> C In-Reply-To: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> References: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> Message-ID: <20040219.145924.48532711.mbj@bluetail.com> ?ke Ai Johansson (LN/EAB) wrote: > Erlang is usually more compact regarding lines of code than for example C. > > Is there a factor that most people agree on? > > If there is: What is the factor and has it been verified in a real > situation, for example when a system has been re-written? I just rewrote a pretty simple tcp/udp server (communicating with a mixture of binary data and xml) in Erlang - the C++ server was some 5000 loc, and the erlang version ~1000. So a factor of 5 in this case, which I think what you usually get. /martin From cyberlync@REDACTED Thu Feb 19 15:23:12 2004 From: cyberlync@REDACTED (Eric Merritt) Date: Thu, 19 Feb 2004 06:23:12 -0800 (PST) Subject: Eclipse plugin advances In-Reply-To: Message-ID: <20040219142312.4898.qmail@web40804.mail.yahoo.com> Vlad, As soon as sourceforge comes up I will add you to as a dev. Its really cool to see some interest in the project. Its been more or less on hold for more then a year as my work situation has been less the optimal and Marc issues crop up in his life as well. --- Vlad Dumitrescu wrote: > Hi, > > I see there's not been any activity at the > erlide.sf.net project for quite a > while. > > I took the JavaEditor example plugin and am working > my way through making it > handle Erlang - so far syntax highlighting works 60% > and it also has some other > useless features. > > I think it would be a good idea not to sit on the > code, and let others > contribute too. :-) > > For this, I'd need to become a developer - Eric or > Marc, could you arrange for > that? My user id is 8024, login name 'vladdu'. > > Thanks in advance, > Vlad __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From mickael.remond@REDACTED Thu Feb 19 15:47:22 2004 From: mickael.remond@REDACTED (Mickael Remond) Date: Thu, 19 Feb 2004 15:47:22 +0100 Subject: Comparing number of lines of code Erlang <-> C In-Reply-To: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> References: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> Message-ID: <20040219144722.GA1170@cgey.com> * ?ke Ai Johansson (LN/EAB) [2004-02-19 13:33:48 +0100]: > Erlang is usually more compact regarding lines of code than for > example C. > > Is there a factor that most people agree on? > > If there is: What is the factor and has it been verified in a real > situation, for example when a system has been re-written? Ulf Wiger has produced a conservative report where his feedback on the ATM AXD 301 report 10 times less lines of code with Erlang compared to C++. He takes conservative figures and arrive to a four time reduction in line of code and thus productivity. The complete report is here: http://www.erlang.se/publications/Ulf_Wiger.pdf Cheers, -- Micka?l R?mond http://www.erlang-projects.org/ From cyberlync@REDACTED Thu Feb 19 16:27:25 2004 From: cyberlync@REDACTED (Eric Merritt) Date: Thu, 19 Feb 2004 07:27:25 -0800 (PST) Subject: Eclipse plugin advances In-Reply-To: Message-ID: <20040219152725.31400.qmail@web40809.mail.yahoo.com> --- Marc van Woerkom wrote: > On Wed, 18 Feb 2004 08:45:07 -0600, Eric Newhuis > wrote: > > Getting code assist working, viewing nice layouted > documentation without > leaving the IDE, incremental search stuff.. I was actually working on this when the job situation fell apart. I have a working info extractor for beam files already. I had intended a complete erlang source parser too. However, I think lukes erlang packages might handle some of this. I need to go in an figure that out. > At some point easy debugging, easy dealing with > mnesia and distribution, > finite state machines and such. Yup. > Perhaps some visual editor for some useful graphical > toolkit (ex11?). That would be cool. GDF could probably even handle it. At the moment there isn't a graphical toolkit to use though. __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From bengt.kleberg@REDACTED Thu Feb 19 17:33:14 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 19 Feb 2004 17:33:14 +0100 Subject: Comparing number of lines of code Erlang <-> C In-Reply-To: <20040219144722.GA1170@cgey.com> References: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> <20040219144722.GA1170@cgey.com> Message-ID: <4034E54A.8000106@ericsson.com> Mickael Remond wrote: ...deleted >Ulf Wiger has produced a conservative report where his feedback >on the ATM AXD 301 report 10 times less lines of code with Erlang >compared to C++. >He takes conservative figures and arrive to a four time reduction in line >of code and thus productivity. > > > just to be overly pedantic. i take it that you mean: and thus an increas in productivity. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ulf.wiger@REDACTED Thu Feb 19 17:56:48 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 19 Feb 2004 17:56:48 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: <20040218005149.GB22613@spearce.org> References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: On Tue, 17 Feb 2004 19:51:49 -0500, Shawn Pearce wrote: > Also due to the effects of the relatively small i-cache on some > processors, a well written emulator can in fact run faster than > native code on very big applications. If the application has very > poor cache locatily in its instruction stream (randomly jumping to > different functions) the i-cache can have a hard time keeping up. > But if you move all of the code into the much larger d-cache (as > in the case of an emulator) you can make the emulator fly > as a much higher percentage of the application can be stored in the > d-cache. Some work has been done on improving these aspects of BEAM, partly due to Thomas Lindgren's work on low-level profiling of AXD 301 code, compiled with HiPE, JAM and BEAM. Bj?rn G. took some of Thomas's findings to heart and improved the cache hit ratio. > Now this is easily worked around by using tools to reorder your native > code functions in the huge application such that they occur in execution > order. I've seen this easily give a 40% performance boost (or more!) > on x86 processors. If you do this, you should easily beat the > emulator. :-) I'm sure, but I've had reason to look at some low-level profiling of large applications written in Rational RoseRT, with a mix of generated and hand-written C++. Lots of pipeline stalls and cache misses > >> >You end up filling up the memory too quickly and soon start >> deterioating >> >performance. >> >> I don't think so - if you take a server with 1 GB RAM, the process vs. >> thread overhead will cut the number of processes you can serve from tens >> of billions to billions (under the worst-case assumption that threads >> don't use any local data on their own). >> As soon as every thread allocates a KByte of memory, the memory overhead >> diminishes to a factor of two, and it decreases further as each thread >> uses more memory. >> But even in the worst case, I suspect that the true bottleneck is the >> CPU, not RAM. > > Its more like RAM bandwidth. Your CPU is most likely stalling on all of > the > context switches due to the amount of data it must keep swapping on and > off > of the chip core. Cycling through a bunch of registers ain't cheap. And > whacking your pipeline on a very deeply pipelined processor is no walk > in the > park either. Then take into account the d-cache, i-cache and TLB misses > you > incur on each switch, and things go downhill very fast. > > Of course, there are applications (like Mozilla!) that will just consume > all > memory on your machine, and then some, so you better not run multiple > copies > of them at once. :-) > >> The quoted IBM paper gave numbers for a concrete test run: a server with >> 9 GB of RAM and eight 700-MHz processors had a near-100% CPU usage, but >> just 36% memory usage (when serving 623 pages per second). >> More interesting is that server performance increased by a factor of >> six (!). Given that Yaws performance was ahead of Apache by a factor of >> roughly 2.5 (at least on the benchmarks posted by Joe), it would be very >> interesting to see how much Yaws profits from the new Linux kernel. > > Well, given that erts is bound to a single processor, you would need to > create a cluster of erts nodes, all running yaws, with some type of load > balancing front end. This is one area Apache really shines in, as it > easily allows this to be setup: because Apache is multi-process already, > it > can easily share the single TCP server socket with all of its siblings > and > decide who gets the next request. > > Does anyone think it might be possible to modify gen_tcp in such a way > that > we could use multiple nodes on the same system all bound to the same TCP > port, > and using some sort of accept lock between them? I'd think this could > be done > something like this: > > % Setup a server socket, but let it be shared by this Erlang node and > all > % other process on this box. > gen_tcp:accept(... [shared]) > > % Have this node take over accepting all new connections. This just > pokes > % the socket into the erts event loop. > gen_tcp:enable_accept(Port) > > % Have this node stop accepting new connections. This just removes the > % socket from the erts event loop. > gen_tcp:disable_accept(Port) > > It might be necessary however (for performance reasons) to let the low > level > C driver also perform its own accept lock using a sys-v IPC sem, flock, > fcntl, > etc, on top of the Erlang managed enable and disable. If the socket is > enabled, then the driver should attempt to grab the accept lock, and only > when it wins it it puts it into the erts event loop. Clearly this might > be difficult as the driver cannot block while trying to grab the accept > lock. > > Note that Linux doesn't require the accept lock I believe... I think its > accept only returns the socket to one process. But I'm not positive. > -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ulf.wiger@REDACTED Thu Feb 19 18:05:06 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 19 Feb 2004 18:05:06 +0100 Subject: Advantages of a large number of threads cf other approaches? In-Reply-To: References: <4031FCCD.4090500@web.de> <20040217122439.GD3109@cgey.com> <403227F5.90405@web.de> <20040218005149.GB22613@spearce.org> Message-ID: On Thu, 19 Feb 2004 17:56:48 +0100, Ulf Wiger wrote: > On Tue, 17 Feb 2004 19:51:49 -0500, Shawn Pearce > wrote: > > >> Also due to the effects of the relatively small i-cache on some >> processors, a well written emulator can in fact run faster than >> native code on very big applications. If the application has very >> poor cache locatily in its instruction stream (randomly jumping to >> different functions) the i-cache can have a hard time keeping up. >> But if you move all of the code into the much larger d-cache (as >> in the case of an emulator) you can make the emulator fly >> as a much higher percentage of the application can be stored in the >> d-cache. > > Some work has been done on improving these aspects of BEAM, partly > due to Thomas Lindgren's work on low-level profiling of AXD 301 > code, compiled with HiPE, JAM and BEAM. Bj?rn G. took some of > Thomas's findings to heart and improved the cache hit ratio. Sorry, I had not intended to send that - not that it contains sensitive or (to my knowledge) incorrect info, but I didn't feel like I had much to add to the discussion. My mouse off and clicked the send button before I could react. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From serge@REDACTED Thu Feb 19 20:05:56 2004 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 19 Feb 2004 14:05:56 -0500 Subject: SS7 & Erlang Message-ID: <40350914.1020202@hq.idt.net> I'd like to ask the Erlang community if anybody knows any projects that implement IN, ISUP, or other SS7 protocols in Erlang. How about STP or SCP Erlang implementations? Serge From erlang@REDACTED Thu Feb 19 20:15:39 2004 From: erlang@REDACTED (Inswitch Solutions - Erlang Evaluation) Date: Thu, 19 Feb 2004 16:15:39 -0300 Subject: Load balancing Message-ID: <007901c3f71c$c4fb14c0$1e00a8c0@design> I have one FSM1 node and several FSMX nodes. FSM1 sends event to one of the FSMX nodes. I have achieved redundancy of FSMX processes using pg2 module. I have already implemented load balancing using statistics(run_queue). How could I achieve a better load balancing? Has someone any good idea? thanks, Eduardo Figoli INSwitch Solutions -------------- next part -------------- An HTML attachment was scrubbed... URL: From ulf.wiger@REDACTED Thu Feb 19 20:45:49 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 19 Feb 2004 20:45:49 +0100 Subject: anniversary Message-ID: On March 1, it will be twenty years since the Ericsson Computer Science Lab was formed, with Bjarne D?cker as manager. I'm giving you advance notice so you can start planning your pilgrimage to ?lvsj?, where it all began. (: For those who understand Swedish, I recommend http://www.erlang.se/publications/jubileumsskrift.html as an entertaining description of the first 10 years at the CS Lab. /Uffe (who had nothing to do with it) -- Ulf Wiger From cpressey@REDACTED Fri Feb 20 03:46:15 2004 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 19 Feb 2004 18:46:15 -0800 Subject: So now all I'd like in Erlang is... In-Reply-To: <20040219002703.GB24157@spearce.org> References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce.org> Message-ID: <20040219184615.1ef33005.cpressey@catseye.mine.nu> On Wed, 18 Feb 2004 19:27:03 -0500 Shawn Pearce wrote: > Chris Pressey wrote: > > How would that work w.r.t. dynamic code reloading? > > I think it would work just like it does now. The only difference is > that when a module is loaded, rather than registering its exported > functions in a table, a module is actually executed. OK. There are still some problems with the approach, though. Mainly - how do you deal with forward references? Even self-references in funs currently have to be done like: Fact = fun (_F, N) when N =< 1 -> 1; (F, N) -> N * F(N - 1) end, Fact(Fact, 23). There are at least three ways you could deal with this: you could adopt Joe's idea for a magical this()-like BIF, or you could do some equally magical prediction when you see "Fact = fun" and consider Fact to be bound even within the body of the fun, or you could force the function to be registered in the export table even if it's solely an internal utility. And that's just self-references. Mutually recursive funs are even more, uh, fun :) They can be done, of course, but they're far from pleasant. I guess what I'm saying is that it *would* be more orthogonal to have all functions as funs, but even if we did, it probably wouldn't be long before something like foo() -> bar was introduced as a shorthand for Foo = fun() -> bar end, register(foo, Foo) anyway. -Chris From spearce@REDACTED Fri Feb 20 03:48:19 2004 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 19 Feb 2004 21:48:19 -0500 Subject: So now all I'd like in Erlang is... In-Reply-To: <20040219184615.1ef33005.cpressey@catseye.mine.nu> References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce.org> <20040219184615.1ef33005.cpressey@catseye.mine.nu> Message-ID: <20040220024819.GA27600@spearce.org> Chris Pressey wrote: > how do you deal with forward references? Uh. Right. Forgot about that. > I guess what I'm saying is that it *would* be more orthogonal to have > all functions as funs, but even if we did, it probably wouldn't be long > before something like foo() -> bar was introduced as a shorthand for > Foo = fun() -> bar end, register(foo, Foo) anyway. You are definately right there. Nice try on my part, but quite a bad idea. :) -- Shawn. From spearce@REDACTED Fri Feb 20 04:42:46 2004 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 19 Feb 2004 22:42:46 -0500 Subject: Getting pipes in overlapped mode on winnt ? Message-ID: <20040220034246.GA27669@spearce.org> Any chance we might someday see an option to port_spawn that would let us set the stdin and stdout pipes to use overlapped IO mode in the child process? I think I'm being forced into creating a pair of threads to emulate overlapped IO (even on Windows NT/2000/XP) just to talk with erts. Or does someone know of a way to convert the standard console handles I get passed by erts into allowing overlapped IO? -- Shawn. "Spock, did you see the looks on their faces?" "Yes, Captain, a sort of vacant contentment." From micke@REDACTED Fri Feb 20 08:38:06 2004 From: micke@REDACTED (micke) Date: Fri, 20 Feb 2004 08:38:06 +0100 Subject: Need Erlang lecturer RESIDENT in (close to Oslo,) Norway Message-ID: <403607C8@epostleser.online.no> Need to locate an Erlang lecturer RESIDENT in (or close to Oslo,) Norway capable of doing a short (up to two hours) SELLING lecture on Erlang... Anyone there ? ---- From francesco@REDACTED Thu Feb 19 12:12:16 2004 From: francesco@REDACTED (Francesco Cesarini (Erlang Consulting)) Date: Thu, 19 Feb 2004 11:12:16 +0000 Subject: Erlang IDE (was Re: Eclipse plugin advances) In-Reply-To: References: Message-ID: <40349A10.9020104@erlang-consulting.com> It is worth adding that the effort being put into developing a good Erlang IDE will pay off with a much much wider user base, so I hope Eric, Marc and Vlad will keep up the good work. Emacs is great, but not suited for everyone... Especially when they are busy learning a new language, the last thing they want to do is to learn a new editor. A straight forward IDE, lots of clicking and easily accessible documentation would certainly facitate the task of getting people to play around with Erlang much more than they are today. (Certainly a different group of people). Only when they are hooked on Erlang we can migrate them and get them hooked to Emacs. :-) Cheers, Francesco -- http://www.erlang-consulting.com Vlad Dumitrescu wrote: > From: "Marc van Woerkom" > >>>I see there's not been any activity at the erlide.sf.net project for >>>quite a while. >> >>It is not lack of interest! > > > I didn't say it is ! :-) > > >>a) Eclipse is huge > > > True. In my experience, in such cases it is easier to start small and build on > incrementally. The Eclipse model lets one do that very nicely. Should the > architecture become messed up, it's also easy to start over. > > >>b) economic pressure > > > Sorry to hear that! > > > I'll try to import the code I have to sourceforge. > > best regards, > Vlad > > From francesco@REDACTED Thu Feb 19 12:12:16 2004 From: francesco@REDACTED (Francesco Cesarini (Erlang Consulting)) Date: Thu, 19 Feb 2004 11:12:16 +0000 Subject: Erlang IDE (was Re: Eclipse plugin advances) In-Reply-To: References: Message-ID: <40349A10.9020104@erlang-consulting.com> It is worth adding that the effort being put into developing a good Erlang IDE will pay off with a much much wider user base, so I hope Eric, Marc and Vlad will keep up the good work. Emacs is great, but not suited for everyone... Especially when they are busy learning a new language, the last thing they want to do is to learn a new editor. A straight forward IDE, lots of clicking and easily accessible documentation would certainly facitate the task of getting people to play around with Erlang much more than they are today. (Certainly a different group of people). Only when they are hooked on Erlang we can migrate them and get them hooked to Emacs. :-) Cheers, Francesco -- http://www.erlang-consulting.com Vlad Dumitrescu wrote: > From: "Marc van Woerkom" > >>>I see there's not been any activity at the erlide.sf.net project for >>>quite a while. >> >>It is not lack of interest! > > > I didn't say it is ! :-) > > >>a) Eclipse is huge > > > True. In my experience, in such cases it is easier to start small and build on > incrementally. The Eclipse model lets one do that very nicely. Should the > architecture become messed up, it's also easy to start over. > > >>b) economic pressure > > > Sorry to hear that! > > > I'll try to import the code I have to sourceforge. > > best regards, > Vlad > > From vlad_dumitrescu@REDACTED Fri Feb 20 10:11:47 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 20 Feb 2004 10:11:47 +0100 Subject: Erlang IDE (was Re: Eclipse plugin advances) References: <40349A10.9020104@erlang-consulting.com> Message-ID: From: "Francesco Cesarini (Erlang Consulting)" > It is worth adding that the effort being put into developing a good > Erlang IDE will pay off with a much much wider user base, so I hope > Eric, Marc and Vlad will keep up the good work. Thanks! > Emacs is great, but not suited for everyone... Especially when they are > busy learning a new language, the last thing they want to do is to learn > a new editor. Or to put it another way, an Eclipse plugin is a good way to show the light to many more Java programmers! :-) > A straight forward IDE, lots of clicking and easily > accessible documentation would certainly facitate the task of getting > people to play around with Erlang much more than they are today. > (Certainly a different group of people). Only when they are hooked on > Erlang we can migrate them and get them hooked to Emacs. :-) There are also things much easier done in Eclipse, just because it's graphical. For example, I think the text variant of a tree display takes too much space on the screen. /Vlad From joachim.durchholz@REDACTED Fri Feb 20 11:42:20 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Fri, 20 Feb 2004 11:42:20 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: <20040219184615.1ef33005.cpressey@catseye.mine.nu> References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce Message-ID: <4035E48C.8010807@web.de> Chris Pressey wrote: > Shawn Pearce wrote: > >>Chris Pressey wrote: >> >>>How would that work w.r.t. dynamic code reloading? >> >>I think it would work just like it does now. The only difference is >>that when a module is loaded, rather than registering its exported >>functions in a table, a module is actually executed. > > OK. There are still some problems with the approach, though. Mainly - > how do you deal with forward references? > > Even self-references in funs currently have to be done like: > > Fact = fun > (_F, N) when N =< 1 -> > 1; > (F, N) -> > N * F(N - 1) > end, > Fact(Fact, 23). Oh, nice - an embryonic Y combinator :-) (Y is a bit more general: it will take any function and "recursify" it.) > There are at least three ways you could deal with this: you could > adopt Joe's idea for a magical this()-like BIF, or you could do some > equally magical prediction when you see "Fact = fun" and consider Fact > to be bound even within the body of the fun, or you could force the > function to be registered in the export table even if it's solely an > internal utility. I must be overlooking something fundamental, so please fill me in where the error is: Assuming the following code: Fact = fun (N) when N =< 1 -> 1 (N) -> Fact (N - 1) end, Fact (23) here's my idea of what will (should, actually *g*) happen: (Never mind the syntax, I'm simply assuming that Fact is a local variable.) The right side of the "Fact =" assignment is a fun. Internally, that fun is just a block of code (bytecode or machine code, details don't really matter). The reference to Fact is compiled into code that says: "retrieve whatever is assigned to the name 'Fact'; crash if Fact is either unassigned or assigned something other than a fun; evaluate parameters and run the fun with them." At the time that this code block is compiled, the value of Fact is not yet known, but that's not a serious problem: it's not run at that time, either. The "Fact (23)" call is compiled just as the recursive call. At run-time, things (could) happen in this order: * Storage is reserved for Fact * The fun is loaded as a constant * "Fact = ..." executed: reference to fun assigned to Fact variable * "Fact (23)" executed: - the fun is looked up from the Fact variable - the fun is called with a parameter of 23 - inside the fun, the recursive call again looks for the fun in Fact - finds the same fun, calls it with 22 - etc. until the recursion terminates The overhead that you have is a lookup in a local variable - an operation that's so common that it should be efficient enough :-) So, my question is: what did I overlook? > And that's just self-references. Mutually recursive funs are even more, > uh, fun :) They can be done, of course, but they're far from pleasant. If you handle them in Y-combinator style, then yes... but it's straightforward: just add all the functions to the parameter list. It's still ugly, of course, but no more ugly than a simple self-referential function :-) > I guess what I'm saying is that it *would* be more orthogonal to have > all functions as funs, but even if we did, it probably wouldn't be long > before something like foo() -> bar was introduced as a shorthand for > Foo = fun() -> bar end, register(foo, Foo) anyway. Actually, if my above description is correct, I'd suggest defining foo () -> bar as a shorthand for foo = fun () -> bar (again, just treating "foo" as a name for a local variable here, not as an atom or anything funny). Regards, Jo -- Currently looking for a new job. From richardc@REDACTED Fri Feb 20 13:25:13 2004 From: richardc@REDACTED (Richard Carlsson) Date: Fri, 20 Feb 2004 13:25:13 +0100 (MET) Subject: So now all I'd like in Erlang is... In-Reply-To: <4035E48C.8010807@web.de> References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce <4035E48C.8010807@web.de> Message-ID: On Fri, 20 Feb 2004, Joachim Durchholz wrote: > The reference to Fact is compiled into code that says: "retrieve > whatever is assigned to the name 'Fact'; crash if Fact is either > unassigned or assigned something other than a fun; evaluate parameters > and run the fun with them." So you want dynamic binding, like in certain Lisp dialects? The problem with that is of course that if someone passes such a fun into some other context where Fact is bound to something completely different (like an integer), it dies horribly. > > And that's just self-references. Mutually recursive funs are even more, > > uh, fun :) They can be done, of course, but they're far from pleasant. > > If you handle them in Y-combinator style, then yes... but it's > straightforward: just add all the functions to the parameter list. Yes, you can do it like this: Odd0 = fun (0, Odd, Even) -> false; (N, Odd, Even) -> Even(N-1, Odd, Even) end, Even0 = fun (0, Odd, Even) -> true; (N, Odd, Even) -> Odd(N-1, Odd, Even) end, Odd = fun (N) -> Odd0(N, Odd0, Even0) end, Even = fun (N) -> Even0(N, Odd0, Even0) end or with a single fun, like this: F = fun ({odd, 0}, F) -> false; ({odd, N}, F) -> F({even, N-1}, F); ({even, 0}, F) -> true; ({even, N}, F) -> F({odd, N-1}, F) end, Odd = fun (N) -> F({odd, N}, F) end, Even = fun (N) -> F({even, N}, F) end (It's not _that_ painful...) /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From Lennart.Ohman@REDACTED Fri Feb 20 13:54:20 2004 From: Lennart.Ohman@REDACTED (=?iso-8859-1?Q?Lennart_=D6hman?=) Date: Fri, 20 Feb 2004 13:54:20 +0100 Subject: SV: Need Erlang lecturer RESIDENT in (close to Oslo,) Norway Message-ID: What qualifies as close to Oslo? No travel cost, I guess!? /Lennart ________________________________ Fr?n: owner-erlang-questions@REDACTED genom micke Skickat: fr 2004-02-20 08:38 Till: erlang-questions@REDACTED ?mne: Need Erlang lecturer RESIDENT in (close to Oslo,) Norway Need to locate an Erlang lecturer RESIDENT in (or close to Oslo,) Norway capable of doing a short (up to two hours) SELLING lecture on Erlang... Anyone there ? ---- -------------- next part -------------- An HTML attachment was scrubbed... URL: From spearce@REDACTED Fri Feb 20 15:15:40 2004 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 20 Feb 2004 09:15:40 -0500 Subject: So now all I'd like in Erlang is... In-Reply-To: References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <4035E48C.8010807@web.de> Message-ID: <20040220141540.GA29258@spearce.org> Richard Carlsson wrote: > On Fri, 20 Feb 2004, Joachim Durchholz wrote: > > > The reference to Fact is compiled into code that says: "retrieve > > whatever is assigned to the name 'Fact'; crash if Fact is either > > unassigned or assigned something other than a fun; evaluate parameters > > and run the fun with them." > > So you want dynamic binding, like in certain Lisp dialects? Uhm, I don't know. What if the following was run in parallel: {Foo, Bar} = {fun(X) Bar(X) end, fun(X) Foo(X) end} ok, so its an infinite loop. But when a fun is compiled, if the fun could automatically assume that all variables which are going to be bound as a result of the fun being created are also bound, as if the had been bound before the expression? This would make self-recursive funs easier to construct, as you would no longer need to pass the fun to itself. It doesn't solve the problem of forward references however. And I think we all agree, we'd just want the shorthand notation back, which is the same syntax we use today. :) -- Shawn. Life is like a 10 speed bicycle. Most of us have gears we never use. -- C. Schultz From hama.biglari@REDACTED Fri Feb 20 14:16:40 2004 From: hama.biglari@REDACTED (Hama Biglari (AS/EAB)) Date: Fri, 20 Feb 2004 14:16:40 +0100 Subject: ERLANG consultants needed in =?iso-8859-1?Q?G=F6teborg?= (Sweden) Message-ID: <403608B8.9EDEAE4@ericsson.com> Hi, Erlang consultants are needed in G?teborg for 6-9 months contract strting 15 March. Do you have 3-5 years telecom's beckground, and strong Erlang programming experience? Then please send your phone number in an email to: hama_biglari@REDACTED Your name, email address and phone number will then be given to a recruitment consultant. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joachim.durchholz@REDACTED Sat Feb 21 03:30:47 2004 From: joachim.durchholz@REDACTED (Joachim Durchholz) Date: Sat, 21 Feb 2004 03:30:47 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce Message-ID: <4036C2D7.9060405@web.de> Richard Carlsson wrote: > On Fri, 20 Feb 2004, Joachim Durchholz wrote: > >> The reference to Fact is compiled into code that says: "retrieve >> whatever is assigned to the name 'Fact'; crash if Fact is either >> unassigned or assigned something other than a fun; evaluate >> parameters and run the fun with them." > > So you want dynamic binding, like in certain Lisp dialects? This depends on what you mean with "dynamic binding". If you mean what I used to call "dynamic scoping", then, no, I don't want this. I want static scoping: as soon as the "Fact" inside the function's body is bound to a value, it should stick with that binding for the rest of its lifetime. But you're right that the rules have to be worded carefully to make this case clear, and I was a bit sloppy here. > The problem with that is of course that if someone passes such a fun > into some other context where Fact is bound to something completely > different (like an integer), it dies horribly. Agreed - dynamic scoping is dangerous. Some people advocate its use for some specific, limited circumstances (I don't, but that's just my taste *g*). Regards, Jo -- Currently looking for a new job. From valentin@REDACTED Sat Feb 21 16:37:13 2004 From: valentin@REDACTED (Valentin) Date: Sat, 21 Feb 2004 17:37:13 +0200 Subject: SS7 & Erlang In-Reply-To: <40350914.1020202@hq.idt.net> References: <40350914.1020202@hq.idt.net> Message-ID: On Thursday 19 February 2004 21:05, Serge Aleynikov wrote: > I'd like to ask the Erlang community if anybody knows any projects that > implement IN, ISUP, or other SS7 protocols in Erlang. How about STP or > SCP Erlang implementations? > > Serge We did subset of MAP (GSM) in Erlang. It works quite well. In addition, we developed, what we called a TCAP Distribution Layer (TCAP-D), that allows the same Point Code to be shared between two or more physically distributed nodes -- each node implements s separate transaction pool, and our software takes care of SCCP routing etc. Valentin. From valentin@REDACTED Sat Feb 21 16:47:13 2004 From: valentin@REDACTED (Valentin) Date: Sat, 21 Feb 2004 17:47:13 +0200 Subject: Erlang IDE (was Re: Eclipse plugin advances) In-Reply-To: References: <40349A10.9020104@erlang-consulting.com> Message-ID: On Friday 20 February 2004 11:11, Vlad Dumitrescu wrote: > From: "Francesco Cesarini (Erlang Consulting)" > > > It is worth adding that the effort being put into developing a good > > Erlang IDE will pay off with a much much wider user base, so I hope > > Eric, Marc and Vlad will keep up the good work. > I am doing a similar thing in VisualSlick -- used it for a year now and works well for me. However, the Eclipse idea might be better considering that VisualSlick is a licensed product, etc. V. From valentin@REDACTED Sat Feb 21 16:54:48 2004 From: valentin@REDACTED (Valentin) Date: Sat, 21 Feb 2004 17:54:48 +0200 Subject: Erlang IDE (was Re: Eclipse plugin advances) In-Reply-To: References: Message-ID: Eclipse... Java VM.... I'll stick with VisualSlick for the time being. V. From robert.virding@REDACTED Sat Feb 21 20:25:20 2004 From: robert.virding@REDACTED (Robert Virding) Date: Sat, 21 Feb 2004 20:25:20 +0100 Subject: Higher order receieve anybody References: Message-ID: <015301c3f8b0$71ba4070$8300a8c0@Rovir> ----- Original Message ----- From: "Joe Armstrong" To: Sent: Tuesday, February 17, 2004 10:10 AM Subject: Higher order receieve anybody > What Uffe and Vlad *really* need is a "higher order" receives ... > > The idea is to rewrite: > > receive > {a, X} -> ... > b -> > Y -> ... > end > > as > > F = fun({a,X}) -> ... > (b) -> ... > (Y) -> ... > end, > Z = receive F, > > > If we introduce an infix ? operator, we'd get: > > Z = ?F I think this would be a very good idea, and quite easy to implement as well. Though there area few potentially difficult points. If I understand what you mean then for receive F end you would evaluate F for each message in the queue with the message as argument. If the function returns a value then that message is "received" and receive returns the function return value. If the functions exits then the message is put back in the queue and we go to the next message. Simple. A few points: 1. Syntactically you still want receive ... end, the syntax of catch was a big mistake so don't repeat it. We don't need more operators. 2. Timeouts would not be handled within the fun but instead have receive F after ... end as before. Having timeouts in the fun would be difficult to define, explain and implement. 3. You wouldn't need to implement this by expanding the fun, you would call it every time. Now for the really tough bit. Semantically this is a nightmare when you really look into it. You get exactly the same problems as for evaluating user defined functions in a guard. A simple example, what happens if you d receive in the receive fun, where do you start in the message queue and where do you stop? Choosing and extracting the message is "guard like" and within it it is difficult to handle user functions. OK, you could say that you handle just just the clause selection bit of the fun as the message selection part and then handle the rhs as the rhs of the fun. This is difficult as the fun was meant to be a general fun and not specially compled. Well set a flag and test at commit time, easy. I think the current compiler has done away with commit, there is no need for. My point is that when you really delve into it it becomes difficult in most respects. Sorry to be a wouser. > So now all I'd like in Erlang is: > > 1) Higher order code > 2) *Proper* structs > 3) !! > 4) Higher order receive > 5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard C) Definitely yes to 1,2 and 5. I don't really see the point of having !!, if I understand it correctly it is just syntactic sugar so why bother. How about replacing ! with erlang:send/2? Robert From thomasl_erlang@REDACTED Sat Feb 21 22:48:56 2004 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Sat, 21 Feb 2004 13:48:56 -0800 (PST) Subject: Higher order receieve anybody In-Reply-To: <015301c3f8b0$71ba4070$8300a8c0@Rovir> Message-ID: <20040221214856.82945.qmail@web41904.mail.yahoo.com> --- Robert Virding wrote: > If I understand what you > mean then for > > receive F end > > you would evaluate F for each message in the queue > with the message as > argument. If the function returns a value then that > message is "received" > and receive returns the function return value. If > the functions exits then > the message is put back in the queue and we go to > the next message. Simple. Maybe there should just be an operation to reify the mailbox (e.g., empty it and make it a list of terms) as well as the other way around (e.g., prepend a list to your own message queue). Then programmers could write receive (with suitable extra operations to code after-clauses) any way they liked and provide those as library functions. However, to grouch a bit, I'd say receive F end seems like tinkering. I'd prefer something with more oomph. (Likewise for !!. And probably structs as well.) > How about replacing ! with erlang:send/2? Nowadays, my code tends to use gen_server:call/2 and suchlike, so I wouldn't mind. Much. Best, Thomas __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From matthias@REDACTED Sun Feb 22 03:31:59 2004 From: matthias@REDACTED (Matthias Lang) Date: Sun, 22 Feb 2004 03:31:59 +0100 Subject: gen_tcp:send with timeout In-Reply-To: References: Message-ID: <16440.5279.793286.750271@antilipe.corelatus.se> Eric Newhuis writes: > Is there a "standard" idiom for calling gen_tcp:send with a timeout? > > I'd like to say gen_tcp:send(Socket, Data, Timeout) but there is no > such (documented) function, my server is queueing, and my process is > blocked forever. Better late than never... One way to do it using documented functions is to spawn a 'disposable' process each time you want to send something, and supervise it with a timer, e.g. Parent = self(), Ref = make_ref(), Disposable = fun() -> ok = gen_tcp:send(S, Bin), Parent ! Ref end, spawn_link(Disposable), receive Ref -> ok after 5000 -> exit(timeout) % or do something more complex end, This is quite general, but it feels roundabout. There's a more direct, but undocumented, variant: inet:setopts(Socket, [{send_timeout, N}]) It would be interesting to know what happens when you use the above option and send a large binary all in one go, e.g.: gen_tcp:send(Socket, Large_binary) and the socket blocks halfway through the binary. It's not documented, so who knows... I haven't investigated. See also: http://www.erlang.org/ml-archive/erlang-questions/200209/msg00076.html Matthias From carsten@REDACTED Sun Feb 22 13:23:17 2004 From: carsten@REDACTED (Carsten Schultz) Date: Sun, 22 Feb 2004 13:23:17 +0100 Subject: optimization question In-Reply-To: References: <20040222082035.GB17778@momenergy.repetae.net> Message-ID: <20040222122316.GE10801@penne.localnet> On Sun, Feb 22, 2004 at 09:41:02AM +0100, Ketil Malde wrote: > John Meacham writes: > > > The reason I ask is I am writing someting which will generate large case > > statements [over strings] and want to know if I should bother > > pre-optimizing it to [search tries]?? > > I've no idea what compilers do, I do not know either, but I think that optimizing pattern matching is probably the one optimization that has been with compilers of functional programs for ever, so I would assume the compiler to do a pretty good job. I am curious for an answer of someone who actually knows, though. Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From carsten@REDACTED Sun Feb 22 14:23:12 2004 From: carsten@REDACTED (Carsten Schultz) Date: Sun, 22 Feb 2004 14:23:12 +0100 Subject: optimization question In-Reply-To: <20040222122316.GE10801@penne.localnet> References: <20040222082035.GB17778@momenergy.repetae.net> <20040222122316.GE10801@penne.localnet> Message-ID: <20040222132311.GG10801@penne.localnet> Sorry, I must be too tired, I responded to the wrong list. BTW, the original question was, if pattern matches are optimized by the (Haskell :-) compiler, and I assume that this would be done by most functional language compilers, including Erlang. Correct? Sorry again, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From spearce@REDACTED Sun Feb 22 19:16:39 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 22 Feb 2004 13:16:39 -0500 Subject: ok or true? Message-ID: <20040222181639.GA2650@spearce.org> This has got to be an age old question: Return 'ok' or 'true' on success? I'm building a gen_serial module. Looking at the gen_tcp API, the functions return 'ok' when they succeed. Looking at the port BIF API, the BIFs all return 'true' when they succeed. So which is it? :-) I've finally got async serial port IO working on Windows XP. I need to get error handling in, and properly terminate the external port servers when the port is closed down, write some edoc, and then I'll release it to the list. Should be sometime later this week. I'd like to get the current serial contrib merged in with this driver too, so both Windows and UNIX can use the same Erlang code. -- Shawn. panic: kernel trap (ignored) From lennart.ohman@REDACTED Sun Feb 22 19:38:56 2004 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Sun, 22 Feb 2004 19:38:56 +0100 Subject: ok or true? In-Reply-To: <20040222181639.GA2650@spearce.org> References: <20040222181639.GA2650@spearce.org> Message-ID: <4038F740.3000303@st.se> Hi, this is of course a matter of religion :-) But I have always preached that one should look at what the opposite return value will be if you have problem deciding. So, if the opposite would be some kind of error ({error,Reason}) then 'ok' denotes a success. One should also use the rule of not making assumptions about what the return value will be used for. With this I mean that ok/error makes such an assumption (about what is desired and what is not). But true/false does not. Good luck :-) /Lennart Shawn Pearce wrote: > This has got to be an age old question: > > Return 'ok' or 'true' on success? > > I'm building a gen_serial module. Looking at the gen_tcp API, the > functions return 'ok' when they succeed. Looking at the port BIF API, > the BIFs all return 'true' when they succeed. > > So which is it? :-) > > I've finally got async serial port IO working on Windows XP. I need > to get error handling in, and properly terminate the external port > servers when the port is closed down, write some edoc, and then I'll > release it to the list. Should be sometime later this week. > > I'd like to get the current serial contrib merged in with this driver > too, so both Windows and UNIX can use the same Erlang code. > -- ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From vances@REDACTED Sun Feb 22 20:02:26 2004 From: vances@REDACTED (Vance Shipley) Date: Sun, 22 Feb 2004 14:02:26 -0500 Subject: ok or true? In-Reply-To: <4038F740.3000303@st.se> References: <20040222181639.GA2650@spearce.org> <4038F740.3000303@st.se> Message-ID: <20040222190226.GC31555@frogman.motivity.ca> I would expect a function which returns true to have only one other possible return value; false. It is my observation that most functions which always succeed return true. I would find a function which returned true or {error, Reason} to be quite odd. -Vance From spearce@REDACTED Sun Feb 22 21:21:32 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 22 Feb 2004 15:21:32 -0500 Subject: ok or true? In-Reply-To: <4038F740.3000303@st.se> References: <20040222181639.GA2650@spearce.org> <4038F740.3000303@st.se> Message-ID: <20040222202132.GA3063@spearce.org> Lennart ?hman wrote: > Hi, this is of course a matter of religion :-) But I have always > preached that one should look at what the opposite return value > will be if you have problem deciding. > > So, if the opposite would be some kind of error ({error,Reason}) > then 'ok' denotes a success. This makes a lot of sense, thanks. > One should also use the rule of not making assumptions about what > the return value will be used for. With this I mean that ok/error > makes such an assumption (about what is desired and what is not). But > true/false does not. This I don't quite understand. If I shouldn't make assumptions about what the return value will be used for, why is ok/error suitable, as it is making the assumption that most times the function will be: case foo() of ok -> ....; {error, Why} -> ... end Yet true/false also makes the assumption that it would be used in a boolean context. This is an old debate, I remember now reading a very long thread on this. That thread also got into the throw/catch and exit/catch, etc. I don't want to reopen the debate. :-) One can usually expect gen_tcp:send, etc. to always return ok. If it doesn't, the caller usually winds up just exiting from their own process, usually with a badmatch. Yet gen_tcp:send returns ok/error. No complaint here, just making an observation. I'm coding with ok/error for my functions. However they should never fail, as the port and the process which owns the port are generally always linked to the caller. (The caller does not trap_exit.) So if something goes wrong, you'd never know. :-) (Actually the supervisor will notice, log the error and restart.) -- Shawn. news: gotcha From spearce@REDACTED Sun Feb 22 21:23:03 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 22 Feb 2004 15:23:03 -0500 Subject: ok or true? In-Reply-To: <20040222190226.GC31555@frogman.motivity.ca> References: <20040222181639.GA2650@spearce.org> <4038F740.3000303@st.se> <20040222190226.GC31555@frogman.motivity.ca> Message-ID: <20040222202303.GB3063@spearce.org> Very good point. I find it interesting the port BIFs return true only. If they have an error to signal, they exit(Error) instead. Which means its unnecessary to actually check their return values. I'll try to keep your point in mind, if I return true, the only other value should be false, making it a perfectly valid boolean function. Vance Shipley wrote: > > I would expect a function which returns true to have only > one other possible return value; false. It is my observation > that most functions which always succeed return true. I > would find a function which returned true or {error, Reason} > to be quite odd. -- Shawn. A wise man can see more from the bottom of a well than a fool can from a mountain top. From ulf.wiger@REDACTED Mon Feb 23 00:24:48 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 23 Feb 2004 00:24:48 +0100 Subject: ok or true? In-Reply-To: <20040222202303.GB3063@spearce.org> References: <20040222181639.GA2650@spearce.org> <4038F740.3000303@st.se> <20040222190226.GC31555@frogman.motivity.ca> <20040222202303.GB3063@spearce.org> Message-ID: On Sun, 22 Feb 2004 15:23:03 -0500, Shawn Pearce wrote: > Very good point. I find it interesting the port BIFs return true only. > If they have an error to signal, they exit(Error) instead. Which means > its unnecessary to actually check their return values. > > I'll try to keep your point in mind, if I return true, the only other > value should be false, making it a perfectly valid boolean function. I would agree with this. I would not use the return value 'true' for anything other than a boolean function with true/false/exit() semantics. A function that returns ok would be expected to perform a side effect (obviously, since it would otherwise be useless.) Such a function should, if it fails, return either {error, Reason} or exit. If possible, the function should limit itself to one basic operation, not the "ok: I've done lots of stuff" semantics. The older (and hopefully wiser) I get, I try more and more to avoid writing functions that simply return ok. gen_tcp:send/2 is a good example of where it's appropriate. Less appropriate uses are e.g.: create_mnesia_tables() -> ..., ok. (It would be better to have a function mnesia_tables() returning a list of tables and properties, and another that creates them, e.g. create_tables(Tabs) -> ok.) /Uffe > Vance Shipley wrote: >> >> I would expect a function which returns true to have only >> one other possible return value; false. It is my observation >> that most functions which always succeed return true. I >> would find a function which returned true or {error, Reason} >> to be quite odd. > -- Ulf Wiger From fgonthier@REDACTED Mon Feb 23 01:36:58 2004 From: fgonthier@REDACTED (fgonthier@REDACTED) Date: Sun, 22 Feb 2004 19:36:58 -0500 Subject: gen_tcp:send failing silently Message-ID: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> Hi all, This weekend, I enjoy some recreational programming with Erlang. I've decided to make a "proof-of-Erlang-goodness" IRC bot to show someone. It's been months since I wrote my last Erlang code and my lack of experience is showing: connection_handle_data(Socket, [Data | R]) -> % Handles PING case regexp:match(Data, "PING :[0-9].*") of {match, _, _} -> Ping_String = string:substring(Data, 6, 16), ok = gen_tcp:send(Socket, io_lib:format("PONG ~s~n", [Ping_String])), io:fwrite("BLARG", []); nomatch -> ok end, factron_translator ! {incoming, Data}, connection_handle_data(Socket, R); connection_handle_data(Socket, []) -> ok. This function is supposed to handle the PING message but the process silently terminates after gen_tcp:send. "BLARG" is never displayed. I've tried all I knew to try to get a clue on the failure, I'm probably missing some debugging techniques. Also, why is that when I write, for example, io:fwrite() in a process, I get a compiler warning, but absolutely no runtime error? The process just seem to go *ZAP* and die :( Fran?ois-Denis From sam@REDACTED Mon Feb 23 02:06:21 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 23 Feb 2004 02:06:21 +0100 Subject: gen_tcp:send failing silently In-Reply-To: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> References: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> Message-ID: <2004-02-23-02-06-21+trackit+sam@rfc1149.net> On 22/02, fgonthier@REDACTED wrote: | This weekend, I enjoy some recreational programming with Erlang. I've | decided to make a "proof-of-Erlang-goodness" IRC bot to show someone. Good idea. If you're willing to see one that I've been developing using OTP, tell me and I'll post the code somewhere (it's work in progress, I didn't want to reuse an old one I had written some years ago). | connection_handle_data(Socket, [Data | R]) -> | % Handles PING | case regexp:match(Data, "PING :[0-9].*") of This is overkill, you should just compare the beginning to "PING " and answer with "PONG " and the rest of the string. | ok = gen_tcp:send(Socket, io_lib:format("PONG ~s~n", [Ping_String])), You do not need to "prepare" the string yourself. You can send a list using gen_tcp:send/2, it will be flattened for you. In your example, that would be something like: ok = gen_tcp:send (Socket, ["PONG ", Ping_String, "\r\n"]) | io:fwrite("BLARG", []); Or simply: io:write ("BLARG~n") (I assume you miss a ~n here). | This function is supposed to handle the PING message but the process | silently terminates after gen_tcp:send. "BLARG" is never displayed. I've | tried all I knew to try to get a clue on the failure, I'm probably missing | some debugging techniques. Are you sure it gets never displayed? Isn't it caused by the missing ~n? | Also, why is that when I write, for example, io:fwrite() in a process, | I get a compiler warning, but absolutely no runtime error? The process just | seem to go *ZAP* and die :( What compiler warning? Sam From spearce@REDACTED Mon Feb 23 02:34:00 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 22 Feb 2004 20:34:00 -0500 Subject: gen_tcp:send failing silently In-Reply-To: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> References: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> Message-ID: <20040223013400.GA3563@spearce.org> I'd try a few things. First, spawn_link the process rather than just spawn it. This way, if it dies, you'll at least get the reason message send back to you on the console. One side-effect to be aware of though: if the shell process has an error (example, you enter "1=2.") you'll take down the process you are developing. I use io:format/2 not io:fwrite/2. Make sure you add a newline in the pattern: io:format("BLARG~n", []). Otherwise you'll get weird looking output, or it may be delayed. The runtime error you are getting but not seeing may be something related to the io:fwrite call, but its doing an exit, and there's nobody trapping the exit and reporting it to you. Use spawn_link like I said above, and at least you'll get the exit message back on the shell. Are you sure its matching the regexp? If it doesn't, you are just dropping right through... and would never see BLARG get sent out. fgonthier@REDACTED wrote: > Hi all, > > This weekend, I enjoy some recreational programming with Erlang. I've > decided to make a "proof-of-Erlang-goodness" IRC bot to show someone. > > It's been months since I wrote my last Erlang code and my lack of > experience is showing: > > connection_handle_data(Socket, [Data | R]) -> > % Handles PING > case regexp:match(Data, "PING :[0-9].*") of > {match, _, _} -> > Ping_String = string:substring(Data, 6, 16), > ok = gen_tcp:send(Socket, io_lib:format("PONG ~s~n", [Ping_String])), > io:fwrite("BLARG", []); > nomatch -> > ok > end, > factron_translator ! {incoming, Data}, > connection_handle_data(Socket, R); > connection_handle_data(Socket, []) -> > ok. > > This function is supposed to handle the PING message but the process > silently terminates after gen_tcp:send. "BLARG" is never displayed. I've > tried all I knew to try to get a clue on the failure, I'm probably missing > some debugging techniques. > > Also, why is that when I write, for example, io:fwrite() in a process, I > get a compiler warning, but absolutely no runtime error? The process just > seem to go *ZAP* and die :( -- Shawn. That does not compute. From fgonthier@REDACTED Mon Feb 23 02:46:26 2004 From: fgonthier@REDACTED (fgonthier@REDACTED) Date: Sun, 22 Feb 2004 20:46:26 -0500 Subject: gen_tcp:send failing silently In-Reply-To: <2004-02-23-02-06-21+trackit+sam@rfc1149.net> Message-ID: <000001c3f9ae$da542840$0200a8c0@VILAIN> Things have evolved since last message. I've managed to put the little bot online. > If you're willing to see one that I've been developing using OTP, tell > me and I'll post the code somewhere (it's work in progress, I didn't want > to reuse an old one I had written some years ago). I wanted to somewhere impress the guy. He hand-coded a channel service bot for our channel in C. The bot is around 5700 lines of C code and I bet to him (and to me as an self-challenge) that I could make a feature-complete clone of it in Erlang in less than 500 lines. His bot has more feature than I expected so I'll be pretty when I'll have an Erlang infobot clone. > | connection_handle_data(Socket, [Data | R]) -> > | % Handles PING > | case regexp:match(Data, "PING :[0-9].*") of > > This is overkill, you should just compare the beginning to "PING " and > answer with "PONG " and the rest of the string. Yeah, that's what I thought too, but the most elegant things with pattern matching is: case Data of [80,73,78,71] -> ... and that gets ugly when the string is longer. I'm probably missing something about pattern-matching. > You do not need to "prepare" the string yourself. You can send a list > using gen_tcp:send/2, it will be flattened for you. In your > example, that > would be something like: > > ok = gen_tcp:send (Socket, ["PONG ", Ping_String, "\r\n"]) Well noted! > Are you sure it gets never displayed? Isn't it caused by the > missing ~n? Okay, that's the part I solved. If you look back at my original message, you can see: Ping_String = string:substring(Data, 6, 16), But, string:substring doesn't exist! It's what was crashing this process. I have coded a custom supervisor process to manage the 3 process (I have yet to pick up on OTP). I used link() to link my workers to my supervisor, expecting the supervisor would receive {'EXIT'...} when other processes failed. I was missing the process_flag(trap_exit, true) call. Because all my processes were linked, when the connection was failing, all my processes died without any error... but still, the process dies with a the 'normal' reason. That's kinda hard to handle... I'm slightly bothered by this behavior. An error like a mistyped function like "substring" should for raise some kind of warning on the console. Perhaps I'm too used to stricter language where such an error is treated as a catastrophe: "Compiler error: OMG! THAT FUNCTION DOESN'T EXIST! RUN FOR YOUR LIFE"... Any advices here? I'm a simple comp. sci. student that usually prefers Java for homeworks. Francois-Denis From fgonthier@REDACTED Mon Feb 23 02:54:06 2004 From: fgonthier@REDACTED (fgonthier@REDACTED) Date: Sun, 22 Feb 2004 20:54:06 -0500 Subject: gen_tcp:send failing silently Message-ID: <000501c3f9af$ec6a5350$0200a8c0@VILAIN> > but still, the process dies with a the 'normal' reason. > That's kinda hard to handle... Nonsense again. I just did a small test in parallel and it works as it should. I'll have to dig deeper in my program to find out why I said that. From sam@REDACTED Mon Feb 23 04:09:22 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 23 Feb 2004 04:09:22 +0100 Subject: gen_tcp:send failing silently References: <2004-02-23-02-06-21+trackit+sam@rfc1149.net> <000001c3f9ae$da542840$0200a8c0@VILAIN> Message-ID: <87u11ize3h.fsf@beeblebrox.enst.fr> > Things have evolved since last message. I've managed to put the > little bot online. Great! > Yeah, that's what I thought too, but the most elegant things with > pattern matching is: > case Data of [80,73,78,71] -> ... > and that gets ugly when the string is longer. I'm probably missing > something about pattern-matching. Implement a full fledged parser for the IRC protocol then. Here is mine: %%-------------------------------------------------------------------- %% Function: parse/1 %% Description: Return a list of arguments in an IRC command. The %% answer is a tuple {Sender, Command} where Sender can %% be false if no server has been detected. %%-------------------------------------------------------------------- parse ([$: | Line]) -> [Sender | Rest] = string:tokens (Line, " "), {false, Command} = parse (join (Rest, " ")), {Sender, Command}; parse (Line) -> [NoNewLine | NewLine] = string:tokens (Line, "\r\n"), [Before | Rest] = string:tokens (NoNewLine, ":"), End = case join (Rest, " ") of [] -> []; X -> [X] end, {false, string:tokens (Before, " ") ++ End}. join ([], _) -> ""; join ([X], _) -> X; join ([X | Xs], C) -> X ++ C ++ join (Xs, C). For example, if you feed parse with "PING :1234567", it will return {false, ["PING", "1234567"]}. > I'm slightly bothered by this behavior. An error like a mistyped > function like "substring" should for raise some kind of warning on > the console. Perhaps I'm too used to stricter language where such > an error is treated as a catastrophe: "Compiler error: OMG! THAT > FUNCTION DOESN'T EXIST! RUN FOR YOUR LIFE"... > Any advices here? I'm a simple comp. sci. student that usually > prefers Java for homeworks. You should use Erlang cross-referencer to look for undefined external functions (try "erl -man xref"). Sam -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From fgonthier@REDACTED Mon Feb 23 06:29:55 2004 From: fgonthier@REDACTED (fgonthier@REDACTED) Date: Mon, 23 Feb 2004 00:29:55 -0500 Subject: gen_tcp:send failing silently In-Reply-To: <87u11ize3h.fsf@beeblebrox.enst.fr> Message-ID: <003201c3f9ce$12d78800$0200a8c0@VILAIN> > parse ([$: | Line]) -> > [Sender | Rest] = string:tokens (Line, " "), > ... [$: | Line] is what was missing to my comprehension. Here is my parser now: parse([$: | Rest]) -> {ok, [Params | Message]} = regexp:split(Rest, " :"), [Source | Details] = string:tokens(Params, " "), {Source, Details ++ case Message of [] -> []; _ -> [join(Message, " :")] end}; parse(Command) -> {system, string:tokens(Command, " :")}. join ([], _) -> ""; join ([X], _) -> X; join ([X | Xs], C) -> X ++ C ++ join (Xs, C). From neumann@REDACTED Sun Feb 22 22:03:34 2004 From: neumann@REDACTED (=?iso-8859-1?Q?Fran=E7ois-Denis_Gonthier?=) Date: Sun, 22 Feb 2004 16:03:34 -0500 Subject: gen_tcp:send failing silently Message-ID: <009201c3f987$564db420$0200a8c0@VILAIN> Hi all, This weekend, I enjoy some recreational programming with Erlang. I've decided to make a "proof-of-Erlang-goodness" IRC bot to show someone. It's been months since I wrote my last Erlang code and my lack of experience is showing: connection_handle_data(Socket, [Data | R]) -> % Handles PING case regexp:match(Data, "PING :[0-9].*") of {match, _, _} -> Ping_String = string:substring(Data, 6, 16), ok = gen_tcp:send(Socket, io_lib:format("PONG ~s~n", [Ping_String])), io:fwrite("BLARG", []); nomatch -> ok end, factron_translator ! {incoming, Data}, connection_handle_data(Socket, R); connection_handle_data(Socket, []) -> ok. This function is supposed to handle the PING message but the process silently terminates after gen_tcp:send. "BLARG" is never displayed. I've tried all I knew to try to get a clue on the failure, I'm probably missing some debugging techniques. Also, why is that when I write, for example, io:fwrite() in a process, I get a compiler warning, but absolutely no runtime error? The process just seem to go *ZAP* and die :( Fran?ois-Denis This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From mickael.remond@REDACTED Mon Feb 23 09:25:11 2004 From: mickael.remond@REDACTED (Mickael Remond) Date: Mon, 23 Feb 2004 09:25:11 +0100 Subject: IRC Bot (Re: gen_tcp:send failing silently) In-Reply-To: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> References: <001101c3f9a5$2613ae90$0200a8c0@VILAIN> Message-ID: <20040223082511.GB2306@cgey.com> * fgonthier@REDACTED [2004-02-22 19:36:58 -0500]: > Hi all, > > This weekend, I enjoy some recreational programming with Erlang. I've > decided to make a "proof-of-Erlang-goodness" IRC bot to show someone. You can take inspiration from Manderlbot: http://www.manderlbot.org/ -- Micka?l R?mond http://www.erlang-projects.org/ From fritchie@REDACTED Mon Feb 23 10:01:59 2004 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Mon, 23 Feb 2004 03:01:59 -0600 Subject: File descriptor passing, was Re: Advantages of a large number of threads.... In-Reply-To: Message of "Wed, 18 Feb 2004 20:41:03 CST." <200402190241.i1J2f352029750@snookles.snookles.com> Message-ID: <200402230902.i1N91x52061709@snookles.snookles.com> Hi there. I put my code where my mouth was. I just checked in to the Jungerl a driver that can pass file descriptors to and from Erlang nodes running on the same machine. It has been lightly tested under Linux & FreeBSD and appears to work. Let me know if you have problems with it ... or fix it yourself! :-) I discovered that it's possible to create a UNIX domain socket with a custom driver, then extract its file descriptor, then use gen_tcp:fdopen/2 to create a socket that has more nifty properties, like all of the options supported by inet:setopts/2. ... Well, I haven't tested that assertion very thoroughly, but it's a quite promising & lazy approach. After all, it would be really nice to be able to use all those nifty features (like SUN RPC or ASN.1 packet type encoding) by using someone else's code (namely the inets driver)! -Scott From spearce@REDACTED Mon Feb 23 10:20:20 2004 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 23 Feb 2004 04:20:20 -0500 Subject: File descriptor passing, was Re: Advantages of a large number of threads.... In-Reply-To: <200402230902.i1N91x52061709@snookles.snookles.com> References: <200402190241.i1J2f352029750@snookles.snookles.com> <200402230902.i1N91x52061709@snookles.snookles.com> Message-ID: <20040223092020.GA5423@spearce.org> Cute trick Scott! I just had to handroll a few of those input scanners that come for free with the inets driver. :-( Its too bad I couldn't do the same thing with my serial driver. I doubt I'll see much ASN.1 on the serial port, but then again... never know! I've always been leary of the fd passing system in UNIX, but if it works, it works. I think its been frowned upon over time, and may be something that kernel developers would love to see die. I know its been used in the past for servers to push the fd off from a network server to the actual work slaves. I think Oracle used it at one point in time, and may still use it actually. Calls like inet:peername/1 may get very confused, neigh, crash something (Erlang caller?) when given a UNIX domain socket. So I'd strongly suggest the caller never know you pulled this magic trick. Otherwise, so long as you steer clear of those calls, I can't see why it would not work. If the socket was a true TCP socket though, it should work just fine. I'd love to know how the performance of a single accepter/dispatcher node and multiple work nodes on a multiple CPU machine compares to say Apache. Bind all of the nodes into a cluster and use process monitoring to automatically migrate the accepter/dispatcher on a crash, and away you go! :) Scott Lystig Fritchie wrote: > Hi there. I put my code where my mouth was. I just checked in to the > Jungerl a driver that can pass file descriptors to and from Erlang > nodes running on the same machine. It has been lightly tested under > Linux & FreeBSD and appears to work. Let me know if you have problems > with it ... or fix it yourself! :-) > > I discovered that it's possible to create a UNIX domain socket with a > custom driver, then extract its file descriptor, then use > gen_tcp:fdopen/2 to create a socket that has more nifty properties, > like all of the options supported by inet:setopts/2. ... Well, I > haven't tested that assertion very thoroughly, but it's a quite > promising & lazy approach. After all, it would be really nice to be > able to use all those nifty features (like SUN RPC or ASN.1 packet > type encoding) by using someone else's code (namely the inets driver)! -- Shawn. From gerd@REDACTED Mon Feb 23 10:31:50 2004 From: gerd@REDACTED (Gerd Flaig) Date: Mon, 23 Feb 2004 10:31:50 +0100 Subject: gen_tcp:send failing silently In-Reply-To: <87u11ize3h.fsf@beeblebrox.enst.fr> (Samuel Tardieu's message of "Mon, 23 Feb 2004 04:09:22 +0100") References: <2004-02-23-02-06-21+trackit+sam@rfc1149.net> <000001c3f9ae$da542840$0200a8c0@VILAIN> <87u11ize3h.fsf@beeblebrox.enst.fr> Message-ID: Samuel Tardieu writes: > Implement a full fledged parser for the IRC protocol then. Here is > mine: out of curiosity - which parser is more efficient, yours or the following one? It is used like this: 1. Get a parser by calling parser(InputFunction). InputFunction should take one argument, a msg record. parser() returns a parser function which takes one string argument. -record(msg, {prefix=[], cmd=[], params=[]}). 2. Call the parser function with your first chunk of data. Whenever a message is complete, the InputFunciton is called. The return value of the parser function is a new parser function which should be called with the next chunk. Suggestions for code improvement are welcome. Goodbyte, Gerd. P.S.: As you can see, I'm also toying around with Erlang and IRC. I'm currently experimenting with a minimal IRC proxy in Erlang. parser(IF) -> fun(String) -> parse(IF, String) end. parse(IF, "") -> parser(IF); parse(IF, [$\n | Rest]) -> parse(IF, Rest); parse(IF, [$: | Rest]) -> prefix(IF, "", Rest); parse(IF, String) -> cmd(IF, "", "", String). prefix(IF, P, "") -> fun(String) -> prefix(IF, P, String) end; prefix(IF, P, [$ | Rest]) -> cmd(IF, lists:reverse(P), "", Rest); prefix(IF, P, [C | Rest]) -> prefix(IF, [C|P], Rest). cmd(IF, Prefix, Cmd, "") -> fun(String) -> cmd(IF, Prefix, Cmd, String) end; cmd(IF, Prefix, Cmd, [$ | Rest]) -> params(IF, #msg{prefix=Prefix, cmd= lists:reverse(Cmd)}, "", Rest); cmd(IF, Prefix, Cmd, [C | Rest]) -> cmd(IF, Prefix, [C | Cmd], Rest). params(IF, M, P, "") -> fun(String) -> params(IF, M, P, String) end; params(IF, M, P, Str = [$\r | Rest]) -> last_param(IF, M, P, Str); params(IF, M, P, [$: | Rest]) -> last_param(IF, M, "", Rest); params(IF, M = #msg{params=Ps}, P, [$ | Rest]) -> params(IF, M#msg{params = [lists:reverse(P) | Ps]}, "", Rest); params(IF, M, P, [C | Rest]) -> params(IF, M, [C | P], Rest). last_param(IF, M = #msg{params=Ps}, P, [$\r | Rest]) -> IF(M#msg{params= lists:reverse([lists:reverse(P) | Ps])}), parse(IF, Rest); last_param(IF, M, P, [C | Rest]) -> last_param(IF, M, [C | P], Rest). -- Gerd Flaig Technik gerd@REDACTED Bei Schlund + Partner AG Brauerstra?e 48 D-76135 Karlsruhe Physics is like sex: sure, it may give some practical results, but that's not why we do it. -- Richard Feynman From bengt.kleberg@REDACTED Mon Feb 23 10:42:17 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Mon, 23 Feb 2004 10:42:17 +0100 Subject: File descriptor passing, was Re: Advantages of a large number of threads.... In-Reply-To: <20040223092020.GA5423@spearce.org> References: <200402190241.i1J2f352029750@snookles.snookles.com> <200402230902.i1N91x52061709@snookles.snookles.com> <20040223092020.GA5423@spearce.org> Message-ID: <4039CAF9.9060506@ericsson.com> Shawn Pearce wrote: >...deleted > >I've always been leary of the fd passing system in UNIX, but if it works, >it works. I think its been frowned upon over time, and may be something >that kernel developers would love to see die. I know its been used > > it is very useful for tightening security. bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From sam@REDACTED Mon Feb 23 10:58:22 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 23 Feb 2004 10:58:22 +0100 Subject: gen_tcp:send failing silently References: <2004-02-23-02-06-21+trackit+sam@rfc1149.net> <000001c3f9ae$da542840$0200a8c0@VILAIN> <87u11ize3h.fsf@beeblebrox.enst.fr> Message-ID: <87ptc6yv5t.fsf@beeblebrox.enst.fr> >>>>> "Gerd" == Gerd Flaig writes: > 2. Call the parser function with your first chunk of > data. Whenever a message is complete, the InputFunciton is > called. The return value of the parser function is a new parser > function which should be called with the next chunk. For simplicity in code, I prefer to acquire input line by line (as offered by gen_tcp). This way, I do not have to handle lines coming from successive chunks or successive lines coming in one chunk. Sam -- Samuel Tardieu -- sam@REDACTED -- http://www.rfc1149.net/sam From ulf.wiger@REDACTED Mon Feb 23 11:11:55 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 23 Feb 2004 11:11:55 +0100 Subject: gen_tcp:send failing silently In-Reply-To: <000001c3f9ae$da542840$0200a8c0@VILAIN> References: <000001c3f9ae$da542840$0200a8c0@VILAIN> Message-ID: On Sun, 22 Feb 2004 20:46:26 -0500, wrote: > I have coded a custom supervisor process to manage the 3 process (I have > yet to pick up on OTP). I used link() to link my workers to my > supervisor, > expecting the supervisor would receive {'EXIT'...} when other processes > failed. I was missing the process_flag(trap_exit, true) call. Because > all my processes were linked, when the connection was failing, all my > processes died without any error... A later message indicates that you solved this problem. For future reference, if you spawn your processes using proc_lib:spawn_link(M,F,A), you will get nicely formatted crash reports when something goes wrong. This assumes that the OTP application SASL is running (either call application:start(sasl,permanent) from the command line or some program, or use 'erl -boot start_sasl') /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joe@REDACTED Mon Feb 23 11:54:51 2004 From: joe@REDACTED (Joe Armstrong) Date: Mon, 23 Feb 2004 11:54:51 +0100 (CET) Subject: ok or true? (fwd) Message-ID: Things that return two possible atoms should *always* return true | false. Why? - because there are loads of library routines which work on predicates. Suppose you have a function switch_status(...) what returns on | off. I'd *immediately* rename this as is_swich_on(...) or switchP(...) that returns true | false Then I can use this as an argument to other Hofs filter(fun is_swich_on/... ) By sticking to bools you increase the chances of being able to use the library functions. In general you should stick to regular return values like {ok, Val} | {error, Why} {value, V} | error for the same reason /Joe > This has got to be an age old question: > > Return 'ok' or 'true' on success? > > I'm building a gen_serial module. Looking at the gen_tcp API, the > functions return 'ok' when they succeed. Looking at the port BIF API, > the BIFs all return 'true' when they succeed. > > So which is it? :-) > > I've finally got async serial port IO working on Windows XP. I need > to get error handling in, and properly terminate the external port > servers when the port is closed down, write some edoc, and then I'll > release it to the list. Should be sometime later this week. > > I'd like to get the current serial contrib merged in with this driver > too, so both Windows and UNIX can use the same Erlang code. > -- ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From joe@REDACTED Mon Feb 23 12:05:54 2004 From: joe@REDACTED (Joe Armstrong) Date: Mon, 23 Feb 2004 12:05:54 +0100 (CET) Subject: Comparing number of lines of code Erlang <-> C In-Reply-To: <9505F6390AA7D311A2D500508B951BEF1457E80A@esealnt427> Message-ID: On Thu, 19 Feb 2004, ?ke Ai Johansson (LN/EAB) wrote: > Erlang is usually more compact regarding lines of code than for example C. > > Is there a factor that most people agree on? No > > If there is: What is the factor and has it been verified in a real situation, for example when a system has been re-written? > Little systems might get re-written but big ones are never re-written with the same functionality, also results from little systems don't scale nicely ... If you re-write in *any* language (say a C->C rewrite) the #code lines will go down and the functionality will go up - so it's very difficult to draw conclusions. In one study (a *long* time ago) a study of the Ericsson MD110 was made and certain functions were re-coded - this got code reduction factors of between 6 and 22 (this is from memory) - but nobody could agree why :-) I think 6 is about right - If you say something over 10 then people would never believe you (even if it were right :-) To be on the safe side get a computer program to print out: > (Ec/C with alpha sub-coalescing of meta-paradigmatic terms) = 5.8764532 /Joe > / ?ke > > This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. > > E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. > > > This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. > > E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. > From joe@REDACTED Mon Feb 23 12:30:50 2004 From: joe@REDACTED (Joe Armstrong) Date: Mon, 23 Feb 2004 12:30:50 +0100 (CET) Subject: So now all I'd like in Erlang is... In-Reply-To: Message-ID: > > >5) A *tiny* implementation (written 99% in Erlang and 1% in ANSI standard > > C) > > > > How tiny do you want to go? > > > > I don't see the point with having a tiny implementation. I like tiny implementations - having a tiny implementation increases the chances that individuals can completely understand *everything*. It make things easy to port and embed > Most important for our customers are stability and speed. If that makes > the implementation more complex (and it does), that's OK. I agree here is a speed x complexity trade off: How do we choose been simple and slow complex and fast I choose the simplest solution which is fast enough. Currently we do research projects to improve performance at the expense of simplicity - but not research into improving simplicity at the expense of performance. Why no research into "slow and simple?" - IMHO such research would lead to Erlang's that are easily portable into hand-held computers and embedded devices etc. It must be small and beautiful because I might have to change it in the future. Beauty is not in the eye of the beholder - it is in the eye of the maintainer :-) At home my 400 MHz celerion is way fast enough for all the Erlang code I have ever written - I have now bought a 2.4 GHz machine - This means I should be able to "pessimise" the Erlang system by a factor 6 and still get the same performance. Suppose this 6 times increase in performance mean that we could write software that was 6 times shorter ... now that would be nice. > > However, we don't want NEEDLESS complexity. Some things are still too > complicated, and we are working on reducing needless complexity and removing > options that are not used. Unfortunately, having to be backwards compatible > prevents us from making all changes we want. > Why the backwards compatibility? - *everybody* (except project managers) hates it. The only argument I've heard that bites is "we don't want to re-test everything" - this argument is correct. It seems like you have to combat "fear of change" with "better testing" - if you could really test *everything* quickly - then surly the fear of changes would go away. Why do do what everybody else does - put new features that everybody wants into the "non backwards compatible version" and charge a hell of a lot to introduce these features into the "old version" Cheers /Joe > > If nothing else, I'd like to see most of the BEAM opcode combination > > stuff in beam_load.c be rolled into the compiler. This would be a > > big win in terms of reducing complexity. > > I doubt that. > > The Beam loader is certainly complex, but it is complexity isolated in > a single place. > > Having the loader there keeps the compiler simpler, and allows us to keep > the beam file format compatible. Essentially, the format is the same from > R5B up to R10B and beyond. (In practice, a few minor details prevent you from > loading and running most R5B modules in R9B and higher, but you can always run > code compiled several releases back.) > > /Bjorn > From thomasl_erlang@REDACTED Mon Feb 23 12:33:50 2004 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Mon, 23 Feb 2004 03:33:50 -0800 (PST) Subject: ok or true? (fwd) In-Reply-To: Message-ID: <20040223113350.9034.qmail@web41902.mail.yahoo.com> --- Joe Armstrong wrote: > > Things that return two possible atoms should > *always* return true | false. What if the function has side effects? > In general you should stick to regular return values > like > > {ok, Val} | {error, Why} > > {value, V} | error > > for the same reason Case in point: lists:keysearch -> {value,X} | false Argh. Oh well, one can always wrap such madness. Come to think of it, this raises a question: why do the standard libraries not make more use of exceptions? For instance, instead of returning {ok, Val} or {error, Why}, one can return Val or exit(Why). There are numerous advantages: the code is shorter, the program is more efficient and if you need to return {ok,Val} or {error, Why}, write a catch-wrapper. Best, Thomas __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From kostis@REDACTED Mon Feb 23 12:45:44 2004 From: kostis@REDACTED (Kostis Sagonas) Date: Mon, 23 Feb 2004 12:45:44 +0100 (MET) Subject: ok or true? (fwd) In-Reply-To: Mail from 'Thomas Lindgren ' dated: Mon, 23 Feb 2004 03:33:50 -0800 (PST) Message-ID: <200402231145.i1NBjimu015226@spikklubban.it.uu.se> Thomas Lindgren wrote: > > > In general you should stick to regular return values > > like > > > > {ok, Val} | {error, Why} > > > > {value, V} | error > > > > for the same reason > > Case in point: > > lists:keysearch -> {value,X} | false > > Argh. Oh well, one can always wrap such madness. I guess list:keysearch HAS to wrap its result, so that it can also return the atom 'false' or 'error' or anything similar. Kostis. From ulf.wiger@REDACTED Mon Feb 23 13:10:33 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Mon, 23 Feb 2004 13:10:33 +0100 Subject: ok or true? (fwd) In-Reply-To: <200402231145.i1NBjimu015226@spikklubban.it.uu.se> References: <200402231145.i1NBjimu015226@spikklubban.it.uu.se> Message-ID: On Mon, 23 Feb 2004 12:45:44 +0100 (MET), Kostis Sagonas wrote: > Thomas Lindgren wrote: > > > > > In general you should stick to regular return values > > > like > > > > > > {ok, Val} | {error, Why} > > > > > > {value, V} | error > > > > > > for the same reason > > > > Case in point: > > > > lists:keysearch -> {value,X} | false > > > > Argh. Oh well, one can always wrap such madness. > > I guess list:keysearch HAS to wrap its result, so that it can > also return the atom 'false' or 'error' or anything similar. Yes, but then {found, Value} | not_found would have been better, or (debatable) {true, Value} | false. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joe@REDACTED Mon Feb 23 13:24:43 2004 From: joe@REDACTED (Joe Armstrong) Date: Mon, 23 Feb 2004 13:24:43 +0100 (CET) Subject: ok or true? (fwd) In-Reply-To: <200402231145.i1NBjimu015226@spikklubban.it.uu.se> Message-ID: > > Case in point: > > > > lists:keysearch -> {value,X} | false > > > > Argh. Oh well, one can always wrap such madness. Youch - this violates the principle of least surprise. If you place you thumb over the "{value,X}" return value and only expose the "false" branch then say: - "guess what the other return value is" most sane people will say "true" when shown that it is in fact "{value, X}" the poor unsuspecting programmer will doubtess show signs of extreme distress. "Functions should be written in such a way as to minimise the astonishement of the user" ... /Joe From fredrik.linder@REDACTED Mon Feb 23 13:43:29 2004 From: fredrik.linder@REDACTED (Fredrik Linder) Date: Mon, 23 Feb 2004 13:43:29 +0100 Subject: ok or true? (fwd) Message-ID: > -----Original Message----- > From: Ulf Wiger > Sent: den 23 februari 2004 13:11 > > On Mon, 23 Feb 2004 12:45:44 +0100 (MET), Kostis Sagonas > wrote: > > > Thomas Lindgren wrote: > > > > > > > In general you should stick to regular return values > > > > like > > > > > > > > {ok, Val} | {error, Why} > > > > > > > > {value, V} | error > > > > > > > > for the same reason > > > > > > Case in point: > > > > > > lists:keysearch -> {value,X} | false > > > > > > Argh. Oh well, one can always wrap such madness. > > > > I guess list:keysearch HAS to wrap its result, so that it can > > also return the atom 'false' or 'error' or anything similar. > > Yes, but then > > {found, Value} | not_found > > would have been better, or (debatable) > > {true, Value} | false. > > /Uffe Or why not use true|false whenever there is a yes/no-style reply, and either {value,Value}|undefined or Value|exit(undefined) when a value is returned. /Fredrik From bengt.kleberg@REDACTED Mon Feb 23 13:44:19 2004 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Mon, 23 Feb 2004 13:44:19 +0100 Subject: ok or true? (fwd) In-Reply-To: <20040223113350.9034.qmail@web41902.mail.yahoo.com> References: <20040223113350.9034.qmail@web41902.mail.yahoo.com> Message-ID: <4039F5A3.7090000@ericsson.com> Thomas Lindgren wrote: > ...deleted > >Come to think of it, this raises a question: why do >the standard libraries not make more use of >exceptions? > > this depends upon _which_ standard libraries one uses :-) i recommend the package_libs(.tar.gz) bundle from ''richardc''. it has better functions, more consistent names and is built with the following conventions: '' Return values in general - A function should *not* return wrapped values like {ok,Value}/{error,Reason} to indicate success or failure. The assumed behaviour should be success, and failures should be signalled by exceptions, as described below. - A function which is evaluated for its side effects only should always return the atom 'ok'; this is the typical Erlang "void" value. '' bengt This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From matthias@REDACTED Mon Feb 23 14:49:03 2004 From: matthias@REDACTED (Matthias Lang) Date: Mon, 23 Feb 2004 14:49:03 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: References: Message-ID: <16442.1231.729546.124747@antilipe.corelatus.se> Joe Armstrong writes: > Why the backwards compatibility? - *everybody* (except project > managers) hates it. Codswallop. > The only argument I've heard that bites is "we don't want to re-test > everything" - this argument is correct. > It seems like you have to combat "fear of change" with "better > testing" - if you could really test *everything* quickly - then surly > the fear of changes would go away. If you had a magic wand which you could wave over a system and have *everything* tested *quickly*, then you'd forever change the face of software development. Where's the wand hidden? Matthias From sam@REDACTED Mon Feb 23 15:18:52 2004 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 23 Feb 2004 15:18:52 +0100 Subject: So now all I'd like in Erlang is... In-Reply-To: <16442.1231.729546.124747@antilipe.corelatus.se> References: <16442.1231.729546.124747@antilipe.corelatus.se> Message-ID: <2004-02-23-15-18-52+trackit+sam@rfc1149.net> On 23/02, Matthias Lang wrote: | If you had a magic wand which you could wave over a system and have | *everything* tested *quickly*, then you'd forever change the face of | software development. | | Where's the wand hidden? Forth? From cyberlync@REDACTED Mon Feb 23 15:28:48 2004 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 23 Feb 2004 06:28:48 -0800 (PST) Subject: So now all I'd like in Erlang is... In-Reply-To: <16442.1231.729546.124747@antilipe.corelatus.se> Message-ID: <20040223142848.3566.qmail@web40808.mail.yahoo.com> --- Matthias Lang wrote: > If you had a magic wand which you could wave over a > system and have > *everything* tested *quickly*, then you'd forever > change the face of > software development. Its called unit testing, its one of the tenents of several schools of programming methodolgy. Unfortunatly, it takes quite a bit of work and most programmers (in my experience) hate writing tests. With this in mind, its not quite as easy as waving a magic wand but the results are more or less the same. __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From david.wallin@REDACTED Mon Feb 23 18:27:29 2004 From: david.wallin@REDACTED (david wallin) Date: Mon, 23 Feb 2004 17:27:29 +0000 Subject: fprof Message-ID: <8E4C74D0-6625-11D8-8F96-000393536F4E@ul.ie> Hi all, I decided to give fprof another go with R9C-0. This is basically how I use fprof: fprof:trace(start), fprof:trace(stop), fprof:profile(), fprof:analyse([{dest, []}, {cols, 120}]). After 'my_stuff' finished, fprof started to read the trace data. After a few minutes and several dots later, fprof outputs: "End of erroneous trace! Processing data... Creating output..." The output contains this line : [{ totals, 20233, 3083.989, 26183.286}]. How can OWN be so much larger than ACC? Is this because the trace file is erroneous, if so, am I using fprof in the wrong way ? How do I go about to get a correct trace? cheers, --david. From robert.virding@REDACTED Mon Feb 23 23:00:33 2004 From: robert.virding@REDACTED (Robert Virding) Date: Mon, 23 Feb 2004 23:00:33 +0100 Subject: So now all I'd like in Erlang is... References: <20040218005825.GC22613@spearce.org> <20040218105559.018ea49a.cpressey@catseye.mine.nu> <20040219002703.GB24157@spearce <4035E48C.8010807@web.de> Message-ID: <004501c3fa58$75971ed0$8300a8c0@Rovir> letrec, that's what you need, letrec. If we are going functional we might as well do it properly. Robert P.S. The we add let as well and add proper variable scoping. No :-) ----- Original Message ----- From: "Richard Carlsson" To: "Joachim Durchholz" Cc: Sent: Friday, February 20, 2004 1:25 PM Subject: Re: So now all I'd like in Erlang is... > > On Fri, 20 Feb 2004, Joachim Durchholz wrote: > > > The reference to Fact is compiled into code that says: "retrieve > > whatever is assigned to the name 'Fact'; crash if Fact is either > > unassigned or assigned something other than a fun; evaluate parameters > > and run the fun with them." > > So you want dynamic binding, like in certain Lisp dialects? > > The problem with that is of course that if someone passes such a > fun into some other context where Fact is bound to something > completely different (like an integer), it dies horribly. > > > > And that's just self-references. Mutually recursive funs are even more, > > > uh, fun :) They can be done, of course, but they're far from pleasant. > > > > If you handle them in Y-combinator style, then yes... but it's > > straightforward: just add all the functions to the parameter list. > > Yes, you can do it like this: > > Odd0 = fun (0, Odd, Even) -> > false; > (N, Odd, Even) -> > Even(N-1, Odd, Even) > end, > Even0 = fun (0, Odd, Even) -> > true; > (N, Odd, Even) -> > Odd(N-1, Odd, Even) > end, > Odd = fun (N) -> Odd0(N, Odd0, Even0) end, > Even = fun (N) -> Even0(N, Odd0, Even0) end > > or with a single fun, like this: > > F = fun ({odd, 0}, F) -> > false; > ({odd, N}, F) -> > F({even, N-1}, F); > ({even, 0}, F) -> > true; > ({even, N}, F) -> > F({odd, N-1}, F) > end, > Odd = fun (N) -> F({odd, N}, F) end, > Even = fun (N) -> F({even, N}, F) end > > (It's not _that_ painful...) > > /Richard > > > Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) > E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ > "Having users is like optimization: the wise course is to delay it." > -- Paul Graham > From robert.virding@REDACTED Mon Feb 23 23:07:00 2004 From: robert.virding@REDACTED (Robert Virding) Date: Mon, 23 Feb 2004 23:07:00 +0100 Subject: ok or true? References: <20040222181639.GA2650@spearce.org> <4038F740.3000303@st.se> <20040222190226.GC31555@frogman.motivity.ca> Message-ID: <006d01c3fa59$5c281570$8300a8c0@Rovir> ----- Original Message ----- From: "Vance Shipley" Sent: Sunday, February 22, 2004 8:02 PM Subject: Re: ok or true? > I would expect a function which returns true to have only > one other possible return value; false. It is my observation > that most functions which always succeed return true. I > would find a function which returned true or {error, Reason} > to be quite odd. Correct. True and false are boolean values and should only be returned if the return value is a boolean value. Otherwise use ok and error/{error,...}. It was a bad design decision that many BIFs and library functions return true or false to signify success and error. We weren't thinking straight when we did that. Robert From robert.virding@REDACTED Mon Feb 23 23:10:08 2004 From: robert.virding@REDACTED (Robert Virding) Date: Mon, 23 Feb 2004 23:10:08 +0100 Subject: ok or true? (fwd) References: Message-ID: <00b101c3fa59$cca00ba0$8300a8c0@Rovir> ----- Original Message ----- From: "Joe Armstrong" To: Sent: Monday, February 23, 2004 11:54 AM Subject: Re: ok or true? (fwd) > Things that return two possible atoms should *always* return true | false. > > Why? - because there are loads of library routines which work on > predicates. > > Suppose you have a function switch_status(...) what returns on | off. > > I'd *immediately* rename this as > > is_swich_on(...) or switchP(...) that returns true | false Ah, but now you have changed the funtions to be boolean functions so then they should naturally return booleans. For the oroiginal functions on|off is better. Robert From robert.virding@REDACTED Mon Feb 23 23:12:46 2004 From: robert.virding@REDACTED (Robert Virding) Date: Mon, 23 Feb 2004 23:12:46 +0100 Subject: ok or true? (fwd) References: <200402231145.i1NBjimu015226@spikklubban.it.uu.se> Message-ID: <00bf01c3fa5a$2ad5a130$8300a8c0@Rovir> ----- Original Message ----- From: "Ulf Wiger" To: Sent: Monday, February 23, 2004 1:10 PM Subject: Re: ok or true? (fwd) > On Mon, 23 Feb 2004 12:45:44 +0100 (MET), Kostis Sagonas > wrote: > > > Thomas Lindgren wrote: > > > > > > > In general you should stick to regular return values > > > > like > > > > > > > > {ok, Val} | {error, Why} > > > > > > > > {value, V} | error > > > > > > > > for the same reason > > > > > > Case in point: > > > > > > lists:keysearch -> {value,X} | false > > > > > > Argh. Oh well, one can always wrap such madness. > > > > I guess list:keysearch HAS to wrap its result, so that it can > > also return the atom 'false' or 'error' or anything similar. > > Yes, but then > > {found, Value} | not_found > > would have been better, or (debatable) > > {true, Value} | false. It would have been much better. We made a mistake. I cleaned up the interface a bit in dict. Robert P.S. Perhaps we should change? :-) From robert.virding@REDACTED Tue Feb 24 01:10:35 2004 From: robert.virding@REDACTED (Robert Virding) Date: Tue, 24 Feb 2004 01:10:35 +0100 Subject: Higher order receieve anybody References: <20040221214856.82945.qmail@web41904.mail.yahoo.com> Message-ID: <009f01c3fa6a$a0488350$8300a8c0@Rovir> ----- Original Message ----- From: "Thomas Lindgren" To: Sent: Saturday, February 21, 2004 10:48 PM Subject: Re: Higher order receieve anybody > > --- Robert Virding wrote: > > If I understand what you > > mean then for > > > > receive F end > > > > you would evaluate F for each message in the queue > > with the message as > > argument. If the function returns a value then that > > message is "received" > > and receive returns the function return value. If > > the functions exits then > > the message is put back in the queue and we go to > > the next message. Simple. > > Maybe there should just be an operation to reify the > mailbox (e.g., empty it and make it a list of terms) > as well as the other way around (e.g., prepend a list > to your own message queue). Then programmers could > write receive (with suitable extra operations to code > after-clauses) any way they liked and provide those as > library functions. That would probably be a cleaner way of doing it. Though it would be a little tricky to handle timeouts. I can't see that there would be real problems with it, though I will have to think abit. How much oomph do you want? Robert From thomasl_erlang@REDACTED Tue Feb 24 08:42:00 2004 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Mon, 23 Feb 2004 23:42:00 -0800 (PST) Subject: Higher order receieve anybody In-Reply-To: <009f01c3fa6a$a0488350$8300a8c0@Rovir> Message-ID: <20040224074200.51297.qmail@web41904.mail.yahoo.com> --- Robert Virding wrote: > That would probably be a cleaner way of doing it. > Though it would be a > little tricky to handle timeouts. I can't see that > there would be real > problems with it, though I will have to think abit. > > How much oomph do you want? Personally, I'm not convinced receive needs much beyond what we already have. Messing around with mailboxes (as I proposed) sounds like a typical "under the hood" issue. (Or are there cases where this is a huge help to the programmer? It might come in handy for erlang-in-erlang, but for application programmers?) Best, Thomas __________________________________ Do you Yahoo!? Yahoo! Mail SpamGuard - Read only the mail you want. http://antispam.yahoo.com/tools From james@REDACTED Tue Feb 24 04:11:13 2004 From: james@REDACTED (James Hague) Date: Mon, 23 Feb 2004 21:11:13 -0600 Subject: Subject: Re: So now all I'd like in Erlang is... Message-ID: <403A6C71.30236.131633@localhost> Bj?rn Gustavsson wrote: > >I don't see the point with having a tiny implementation. > >Most important for our customers are stability and >speed. If that makes the implementation more complex >(and it does), that's OK. I agree that speed and reliability are important, and I am in awe of the speed of the current emulator. But I also think that Erlang could better evolve, and we'd see more experimental changes to the language outside of Ericsson, if there was a smaller, cleaner implementation of the language. As it stands, the Erlang runtime is pretty difficult to hack, especially without documentation. James This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From james@REDACTED Tue Feb 24 04:11:14 2004 From: james@REDACTED (James Hague) Date: Mon, 23 Feb 2004 21:11:14 -0600 Subject: Erlang + Forth?!? Message-ID: <403A6C72.1947.1316DA@localhost> > Ok what about Forth, the forth has the tiny interpreter (talking >about a few bytes). I have had a project >that has been in my mind for years. That is to rewrite >the erlang runtime system in forth Oddly enough, I have thought about this as well. It is relatively easy to write a machine code generating, optimizing compiler for a subset of Forth. You get some big wins when it comes to writing an emulator, such as tail recursion and very lightweight subroutine calls, plus you can test interactively. This kind of application is what Forth is perfect for. I've written a few mini-forths in Erlang. It would be interesting to take one all the way through the optimization stage. James This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ulf.wiger@REDACTED Tue Feb 24 09:48:12 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 09:48:12 +0100 Subject: Higher order receieve anybody In-Reply-To: <20040224074200.51297.qmail@web41904.mail.yahoo.com> References: <20040224074200.51297.qmail@web41904.mail.yahoo.com> Message-ID: On Mon, 23 Feb 2004 23:42:00 -0800 (PST), Thomas Lindgren wrote: > > --- Robert Virding wrote: >> That would probably be a cleaner way of doing it. >> Though it would be a little tricky to handle timeouts. >> I can't see that there would be real problems with it, >> though I will have to think abit. >> >> How much oomph do you want? > > Personally, I'm not convinced receive needs much > beyond what we already have. Messing around with > mailboxes (as I proposed) sounds like a typical "under > the hood" issue. (Or are there cases where this is a > huge help to the programmer? It might come in handy > for erlang-in-erlang, but for application > programmers?) I do not see much need for application programmers messing around with the mailbox. There are almost always fairly simple workarounds in the cases where it might be warranted. Handling system messages is the one area where I've found it necessary to raise the abstraction level above what 'receive' provides. There are workarounds -- they are called gen_server and gen_fsm, but they have the unfortunate side-effect of imposing an un-erlangish message reception paradigm on the unsuspecting user. I would like to see the possibility to divide messages into two separate categories: administrative (such as suspend, resume, inspect, upgrade) and operative (whatever the program is _really_ supposed to do. And I would like to be able to keep them separated without messing up the programming semantics. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From ulf.wiger@REDACTED Tue Feb 24 10:20:43 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 10:20:43 +0100 Subject: link to documentation Message-ID: I noticed that http://www.erlang.org/doc.html contains a link to the OTP R9B documentation, but not the R9C docs. Even so, the R9C docs are there: http://www.erlang.org/doc/r9c/doc/index.html I've not noticed this before, and reloaded the page twice to make sure I wasn't just looking at an old page. A recent glitch? /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From vlad_dumitrescu@REDACTED Tue Feb 24 10:22:08 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 24 Feb 2004 10:22:08 +0100 Subject: Higher order receieve anybody References: <20040224074200.51297.qmail@web41904.mail.yahoo.com> Message-ID: From: "Ulf Wiger" > Handling system messages is the one area where I've found it > necessary to raise the abstraction level above what 'receive' > provides. There are workarounds -- they are called gen_server > and gen_fsm, but they have the unfortunate side-effect of > imposing an un-erlangish message reception paradigm on the > unsuspecting user. I agree fully. > I would like to see the possibility to divide messages into > two separate categories: administrative (such as suspend, > resume, inspect, upgrade) and operative (whatever the program > is _really_ supposed to do. And I would like to be able to keep > them separated without messing up the programming semantics. I could even imagine such a separation hard-wired into the language (i.e. the normal receive would work like Ulf's extended receive). Yes, there would be a change in semantics, but almost no one would notice it because normal uses are not affected. Handling system messages would be done behind the scenes by a default handler, but this should be customizable. Then the next generation of gen_server and friends will look a lot more like regular processes! :-) regards, Vlad From kent@REDACTED Tue Feb 24 11:15:16 2004 From: kent@REDACTED (Kent Boortz) Date: 24 Feb 2004 11:15:16 +0100 Subject: link to documentation In-Reply-To: References: Message-ID: Ulf Wiger writes: > I noticed that http://www.erlang.org/doc.html contains a link to the > OTP R9B documentation, but not the R9C docs. Even so, the R9C docs > are there: > > http://www.erlang.org/doc/r9c/doc/index.html > > I've not noticed this before, and reloaded the page twice to make > sure I wasn't just looking at an old page. A recent glitch? Strange, I was 100% I scanned the doc for all R9B references and changed them but obviously I did not. I have done that now and also updated the search index, kent This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From carsten@REDACTED Tue Feb 24 12:58:47 2004 From: carsten@REDACTED (Carsten Schultz) Date: Tue, 24 Feb 2004 12:58:47 +0100 Subject: Erlang external term format Message-ID: <20040224115846.GC23238@penne.localnet> Hi, is the Erlang external term format documented anywhere? I could not find any pointers and am not to keen on reading the fine source. Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From vlad_dumitrescu@REDACTED Tue Feb 24 14:31:24 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 24 Feb 2004 14:31:24 +0100 Subject: Erlang external term format References: <20040224115846.GC23238@penne.localnet> Message-ID: Hi, look into erts/emulator/internal_doc in the sources. regards, Vlad From spearce@REDACTED Tue Feb 24 15:09:31 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 24 Feb 2004 09:09:31 -0500 Subject: Higher order receieve anybody In-Reply-To: References: <20040224074200.51297.qmail@web41904.mail.yahoo.com> Message-ID: <20040224140931.GA9146@spearce.org> This is a pretty good idea. Except that the 'system' category should be extensible, so behaviors can add their own notion of what 'system' is. For example, some of my behaviors I'd like to have inspect messages that the end-developer doesn't have to get involved in; as the behavior offers those services to the developer. If receive F end was possible, it might be nice to register a fun in a process_flag, e.g. process_flag(system_message_handler, F). When the user application wants to accept system messages, the receive call adds another keyword: receive system; ... -> ... end. The runtime scans the mailbox for the first message that matches either the current receive pattern, or the fun set as the system_message_handler. The only issue is where do you resume execution after the sys module has processed the message... I think higher order receive is a lot like my "why aren't modules just sets of variables bound to funs" question. :) Sure its nice and all, but the reality is, most developers would prefer to write: receive {foo, ...} -> ... end over receive fun({foo, ...}) -> .. end end any day. But it does at least allow usage like: plain_fsm_receive(fun({foo, ...}) -> ... end) assuming that the higher order receive allowed multiple funs at once: plain_fsm_receive(F) -> SytemHandler = fun(...) -> ... end, receive SystemHandler, F end. But then I'd have to just ask for erlang:receive([F]), as in: receive([SystemHandler, F]). and say forget keywords. The receive keyword is only nice as a syntatic sugar form of the receive BIF and a list of 0 argument funs, created from the body of the keyword. One problem with system messages is how processing resumes. In fact, I think that is the more difficult part of this discussion; as there is no one way to behave after a system message is processed... Ulf Wiger wrote: > I do not see much need for application programmers messing > around with the mailbox. There are almost always fairly > simple workarounds in the cases where it might be warranted. > > Handling system messages is the one area where I've found it > necessary to raise the abstraction level above what 'receive' > provides. There are workarounds -- they are called gen_server > and gen_fsm, but they have the unfortunate side-effect of > imposing an un-erlangish message reception paradigm on the > unsuspecting user. > > I would like to see the possibility to divide messages into > two separate categories: administrative (such as suspend, > resume, inspect, upgrade) and operative (whatever the program > is _really_ supposed to do. And I would like to be able to keep > them separated without messing up the programming semantics. -- Shawn. While riding in a train between London and Birmingham, a woman inquired of Oscar Wilde, "You don't mind if I smoke, do you?" Wilde gave her a sidelong glance and replied, "I don't mind if you burn, madam." From tony@REDACTED Tue Feb 24 15:11:46 2004 From: tony@REDACTED (Tony Rogvall) Date: Tue, 24 Feb 2004 15:11:46 +0100 Subject: Higher order receieve anybody In-Reply-To: Message-ID: <614367EC-66D3-11D8-AE38-000A95EB4F88@rogvall.com> On Tuesday, Feb 24, 2004, at 09:48 Europe/Stockholm, Ulf Wiger wrote: > > I would like to see the possibility to divide messages into > two separate categories: administrative (such as suspend, > resume, inspect, upgrade) and operative (whatever the program > is _really_ supposed to do. And I would like to be able to keep > them separated without messing up the programming semantics. One idea (tested and implemented) is to use a primitive erlang:signal(Pid,Sig, Info) to send a primitive form of messages. For example message passing could be implemented as erlang:signal(Pid, 'MESSAGE', Message). In Multi Pro Erlang we did the signal dispatcher in C code. In retrospect we should have implemented a signal dispatcher / signal_handler in Erlang. This way all signals (including messages) would be processed by Erlang code. Then one could implement the link semantics and message reception etc in Erlang code! The signal handler should be called in the context of the receiving process with some kind of interrupt semantics (when it comes to receive). -module(signal_handler). -export([handle_signal/3]). handle_signal(From, 'MESSAGE', Message) -> erlang:queue_message(Message); handle_signal(From, 'LINK', _) -> erlang:add_link(From); ... /Tony > /Uffe > -- > Ulf Wiger, Senior System Architect > EAB/UPD/S > > This communication is confidential and intended solely for the > addressee(s). Any unauthorized review, use, disclosure or distribution > is prohibited. If you believe this message has been sent to you in > error, please notify the sender by replying to this transmission and > delete the message without disclosing it. Thank you. > > E-mail including attachments is susceptible to data corruption, > interruption, unauthorized amendment, tampering and viruses, and we > only send and receive e-mails on the basis that we are not liable for > any such corruption, interception, amendment, tampering or viruses or > any consequences thereof. From ulf.wiger@REDACTED Tue Feb 24 15:23:21 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 15:23:21 +0100 Subject: Higher order receieve anybody In-Reply-To: <614367EC-66D3-11D8-AE38-000A95EB4F88@rogvall.com> References: <614367EC-66D3-11D8-AE38-000A95EB4F88@rogvall.com> Message-ID: On Tue, 24 Feb 2004 15:11:46 +0100, Tony Rogvall wrote: > One idea (tested and implemented) is to use a primitive > erlang:signal(Pid,Sig, Info) to send a primitive form of messages. For > example message passing could be implemented as erlang:signal(Pid, > 'MESSAGE', Message). In Multi Pro Erlang we did the signal dispatcher in > C code. In retrospect we should have implemented > a signal dispatcher / signal_handler in Erlang. This way > all signals (including messages) would be processed by Erlang code. Then > one could implement the link semantics and message reception etc in > Erlang code! > The signal handler should be called in the context of the receiving > process with some kind of interrupt semantics (when it comes to receive). > > > -module(signal_handler). > -export([handle_signal/3]). > > handle_signal(From, 'MESSAGE', Message) -> > erlang:queue_message(Message); > handle_signal(From, 'LINK', _) -> > erlang:add_link(From); > ... Very nice! (: /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From carsten@REDACTED Tue Feb 24 15:43:14 2004 From: carsten@REDACTED (Carsten Schultz) Date: Tue, 24 Feb 2004 15:43:14 +0100 Subject: Erlang external term format In-Reply-To: References: <20040224115846.GC23238@penne.localnet> Message-ID: <20040224144313.GH23238@penne.localnet> > look into erts/emulator/internal_doc in the sources. Thanks, that looks like what i was looking for. Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From vlad_dumitrescu@REDACTED Tue Feb 24 15:51:26 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 24 Feb 2004 15:51:26 +0100 Subject: Higher order receieve anybody References: <20040224074200.51297.qmail@web41904.mail.yahoo.com> <20040224140931.GA9146@spearce.org> Message-ID: From: "Shawn Pearce" > One problem with system messages is how processing resumes. In fact, > I think that is the more difficult part of this discussion; as there > is no one way to behave after a system message is processed... Could you please elaborate a little? I only see one way that is "natural" - handling system messages is transparent and processing stays in the receive loop. > ... and say forget keywords. The receive keyword is only nice as a > syntatic sugar form of the receive BIF and a list of 0 argument funs, > created from the body of the keyword. I say: let's get rid of all keywords! :-) What do we get then? No, not Forth, but Lisp. Seriously. regards, Vlad From vlad_dumitrescu@REDACTED Tue Feb 24 15:59:46 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 24 Feb 2004 15:59:46 +0100 Subject: Higher order receieve anybody References: <614367EC-66D3-11D8-AE38-000A95EB4F88@rogvall.com> Message-ID: From: "Tony Rogvall" > > One idea (tested and implemented) is to use a primitive > erlang:signal(Pid,Sig, Info) to send > a primitive form of messages. For example message passing could be > implemented as > erlang:signal(Pid, 'MESSAGE', Message). In Multi Pro Erlang we did the > signal dispatcher in C code. > In retrospect we should have implemented a signal dispatcher / > signal_handler in Erlang. This way > all signals (including messages) would be processed by Erlang code. > Then one could implement > the link semantics and message reception etc in Erlang code! > The signal handler should be called in the context of the receiving > process with some kind of > interrupt semantics (when it comes to receive). > > > -module(signal_handler). > -export([handle_signal/3]). > > handle_signal(From, 'MESSAGE', Message) -> > erlang:queue_message(Message); > handle_signal(From, 'LINK', _) -> > erlang:add_link(From); > ... Super cool! /Vlad From ulf.wiger@REDACTED Tue Feb 24 16:13:15 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 16:13:15 +0100 Subject: The New and Improved edoc Message-ID: I have a question regarding the new and improved edoc (apart from "when will it appear in Jungerl?") When documenting behaviours, one wants to specify the required callback functions in a manner similar to the gen_server documentation. How does one do that? Does edoc offer a standard way of doing it, or will I have to "fake it" in the module documentation? (I confess to not having meditated over the edoc source to find the answer...) /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From richardc@REDACTED Tue Feb 24 16:43:51 2004 From: richardc@REDACTED (Richard Carlsson) Date: Tue, 24 Feb 2004 16:43:51 +0100 (MET) Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Tue, 24 Feb 2004, Ulf Wiger wrote: > I have a question regarding the new and improved edoc > (apart from "when will it appear in Jungerl?") As soon as someone puts it there? Go ahead - if anyone adds something to it, I can pick it up and include it in the "official version". Sadly, I have been too bogged down with More Important Things to do the last couple of months, so I've hardly touched the code since Christmas. > When documenting behaviours, one wants to specify the required > callback functions in a manner similar to the gen_server documentation. > > How does one do that? Does edoc offer a standard way of doing it, or > will I have to "fake it" in the module documentation? Ideally, there should be facilities for grouping things (functions, etc.) under different headings. But that's for functions that are actually defined in the module. The new edoc already documents that a module implements a particular behaviour (if it contains "-behaviour(xxx).") It could also be made to recognize the behaviour_info/1 function and present the callback functions automatically. But the only information available is the names and arities of the callbacks. The question is how to document the callbacks in more detail. A straightforward way of doing it is of course to provide a dummy callback module, and refer to that for the documentation. If you don't like that solution, you'll just have to document the callbacks in a "hard-coded" manner using HTML in the edoc comments, for now anyway. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From ulf.wiger@REDACTED Tue Feb 24 17:36:46 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 17:36:46 +0100 Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Tue, 24 Feb 2004 16:43:51 +0100 (MET), Richard Carlsson wrote: > On Tue, 24 Feb 2004, Ulf Wiger wrote: > >> I have a question regarding the new and improved edoc >> (apart from "when will it appear in Jungerl?") > > As soon as someone puts it there? Go ahead - if anyone adds > something to it, I can pick it up and include it in the > "official version". Since there is already an older version of edoc there, I'd be afraid of putting up a new version without knowing what has changed. Why don't you do it? I noticed that you're not a registered developer, but I'm sure that can be amended. (: Another feature request: When using edoc:application/1, an index page is created with links to the doc pages for each module -- very nice, but there isn't a link back to the top page (index.html), which is a slight nuisance. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From richardc@REDACTED Tue Feb 24 17:42:22 2004 From: richardc@REDACTED (Richard Carlsson) Date: Tue, 24 Feb 2004 17:42:22 +0100 (MET) Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Tue, 24 Feb 2004, Ulf Wiger wrote: > Another feature request: > > When using edoc:application/1, an index page is created with > links to the doc pages for each module -- very nice, but there > isn't a link back to the top page (index.html), which is a slight > nuisance. Your browser doesn't have a "back" button? :-) Seriously, though, there should be proper navigation bars both at the top and the bottom of every page. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From ulf.wiger@REDACTED Tue Feb 24 18:22:29 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Tue, 24 Feb 2004 18:22:29 +0100 Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Tue, 24 Feb 2004 17:42:22 +0100 (MET), Richard Carlsson wrote: Since this is going well, I press on with feature requests. (: I'd like to be able to indicate with some macro that the actual function implementation be included as documentation. This would be especially useful when providing an example behaviour callback. I know I can copy and paste the code wrapped in
...
,
but it would be nice to eliminate that step.

An example -- perhaps not the best way to express it, but I'm on my
way home:

%% @spec handle_leader_call(Msg::term(), From::callerRef(), State::term(),
%%                          E::election()) ->
%%    {reply, Reply, NewState} |
%%    {reply, Reply, Broadcast, NewState} |
%%    {noreply, NewState} |
%%    {stop, Reason, Reply, NewState} |
%%    commonReply()
%%
%% @doc Called by the leader in response to a
%% {@link gen_leader:leader_call/2. leader_call()}.
%% 

If the return value includes a Broadcast object, it will %% be sent to all candidates, and they will receive it in the function %% {@link from_leader/3. from_leader/3}.

%%

Example:

%% {@include_code} handle_leader_call({store,F}, From, Dict, E) -> NewDict = F(Dict), {reply, ok, {store, F}, NewDict}; handle_leader_call({leader_lookup,F}, From, Dict, E) -> Reply = F(Dict), {reply, Reply, Dict}. %% {@end_include_code} %%@end /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From cpressey@REDACTED Wed Feb 25 02:24:12 2004 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 24 Feb 2004 17:24:12 -0800 Subject: [OT] "e"erie coincidence... Message-ID: <20040224172412.347f0947.cpressey@catseye.mine.nu> If you're bored, check out this site: http://www.emedicine.com/ There's something oddly familiar about their logo, but I just can't put my finger on it... :) -Chris From ok@REDACTED Wed Feb 25 04:09:07 2004 From: ok@REDACTED (Richard A. O'Keefe) Date: Wed, 25 Feb 2004 16:09:07 +1300 (NZDT) Subject: Higher order receieve anybody Message-ID: <200402250309.i1P397eo273378@atlas.otago.ac.nz> Ulf Wiger wrote: Handling system messages is the one area where I've found it necessary to raise the abstraction level above what 'receive' provides. There are workarounds -- they are called gen_server and gen_fsm, but they have the unfortunate side-effect of imposing an un-erlangish message reception paradigm on the unsuspecting user. I would like to see the possibility to divide messages into two separate categories: administrative (such as suspend, resume, inspect, upgrade) and operative (whatever the program is _really_ supposed to do. And I would like to be able to keep them separated without messing up the programming semantics. Colour me stupid, but why not have two processes? One to do the real work, and one to handle the administrative messages and forward stuff to the worker? What am I missing here? From spearce@REDACTED Wed Feb 25 04:41:44 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 24 Feb 2004 22:41:44 -0500 Subject: Higher order receieve anybody In-Reply-To: <200402250309.i1P397eo273378@atlas.otago.ac.nz> References: <200402250309.i1P397eo273378@atlas.otago.ac.nz> Message-ID: <20040225034144.GA10730@spearce.org> "Richard A. O'Keefe" wrote: > Colour me stupid, but why not have two processes? > One to do the real work, and one to handle the administrative > messages and forward stuff to the worker? > What am I missing here? The messages are stuff like: "Yo! You need to stop working now so we can safely upgrade a whole wad of code. Go to sleep for a few seconds!" "Yo! Your code has changed! Somehow make an external call back into yourself to get the new version." "Yo! Your code has changed! You might want to migrate your old state data to its new internal format, if the new code says you need to." "Hey stupid! Your parent is dead. You should stop processing now because your parent was a supervisor, and you claimed you were a good OTP citizen when you signed up with it." All stuff the work must do himself... The suspend (sleep, the first one) is necessary to be selective, not all states may allow suspending the process. gen_server, gen_fsm, gen_event all allow suspend any time, which isn't ideal. -- Shawn. "First, we would not accept a treaty that would not have been ratified, nor a treaty that I thought made sense for the country." George W. Bush April 24, 2001 Referring to the Kyoto Accord. From an interview published in the Washington Post. From spearce@REDACTED Wed Feb 25 04:48:21 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 24 Feb 2004 22:48:21 -0500 Subject: sends don't block, right? Message-ID: <20040225034821.GB10730@spearce.org> Ok, colo(u)r me stupid now (borrowed phrase, sorry!): ! doesn't block, right? If I do something foolish like this: never_end() -> Pid = spawn(fun() -> receive foo -> ok end), do_loop(Pid). do_loop(Pid) -> Pid ! bar, io:format("still going, just like the bunny~n", []), do_loop(Pid). will the parent ever stop because the child's message buffer is full? Basically, I'm asking if Erlang will let the parent in this case run the VM out of memory before making the parent freeze. Clearly one should never write this code, but I'm trying to setup an async-send for my serial driver that will "never" block the caller, as apposed to the blocking send which makes sure the data was delivered to the endpoint before returning. The only reason I'm concerned here is the caller could lock up if it gets blocked and hardware or software flow control breaks down due to link failure. With most serial protocols I wouldn't see the need to buffer more than a few hundred KB of data, and the port driver already has buffers deep enough to handle that, so in theory, port_command/2 should never block. I just want to keep from blocking up the application, if the application so desires. -- Shawn. C Code. C Code Run. Run, Code, RUN! PLEASE!!!! From cpressey@REDACTED Wed Feb 25 05:19:09 2004 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 24 Feb 2004 20:19:09 -0800 Subject: sends don't block, right? In-Reply-To: <20040225034821.GB10730@spearce.org> References: <20040225034821.GB10730@spearce.org> Message-ID: <20040224201909.2e351791.cpressey@catseye.mine.nu> On Tue, 24 Feb 2004 22:48:21 -0500 Shawn Pearce wrote: > Ok, colo(u)r me stupid now (borrowed phrase, sorry!): > > ! doesn't block, right? Right. > If I do something foolish like this: > > never_end() -> > Pid = spawn(fun() -> receive foo -> ok end), > do_loop(Pid). > > do_loop(Pid) -> > Pid ! bar, > io:format("still going, just like the bunny~n", []), > do_loop(Pid). > > will the parent ever stop because the child's message buffer is full? No. It'll crash. By which I mean the Erlang *node* will crash, not just the process. > Basically, I'm asking if Erlang will let the parent in this case run > the VM out of memory before making the parent freeze. Yes, exactly that. At least, that was my experience last time I tried anything like this. Perhaps try it yourself and see? -Chris From spearce@REDACTED Wed Feb 25 05:45:02 2004 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 24 Feb 2004 23:45:02 -0500 Subject: sends don't block, right? In-Reply-To: <20040224201909.2e351791.cpressey@catseye.mine.nu> References: <20040225034821.GB10730@spearce.org> <20040224201909.2e351791.cpressey@catseye.mine.nu> Message-ID: <20040225044502.GA10986@spearce.org> Chris Pressey wrote: > On Tue, 24 Feb 2004 22:48:21 -0500 > Shawn Pearce wrote: > > > Basically, I'm asking if Erlang will let the parent in this case run > > the VM out of memory before making the parent freeze. > > Yes, exactly that. Excellent, that's what I had thought, but its been a while since I had last read that fact and/or proved it to myself by reading that section of the emulator source code. Not that I'd ever condone taking a node down like this. But the fact that Erlang will grow the buffers as needed is what I'd expect. In truth, my serial port 'user' processes will notice something is amiss long before they ever put over a MB or two into a message queue. > At least, that was my experience last time I tried anything like this. > Perhaps try it yourself and see? Nah. I'm not that worried about it. It was easier to email the list and get a response from someone like yourself who knows Erlang better than I, than to run a node for hours trying to fill up main memory until the node crashes. When you have a full 1 GB of RAM available to the node its gonna take a while to run that test case I posted. Thanks for the quick reply Chris. -- Shawn. I'm continually AMAZED at th'breathtaking effects of WIND EROSION!! From spearce@REDACTED Wed Feb 25 08:19:39 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 02:19:39 -0500 Subject: gen_serial-0.1 release out Message-ID: <20040225071939.GA12572@spearce.org> FWIW, I have a (what appears to be) working serial port driver for Windows. I plan to have UNIX support within a few days. http://www.spearce.org/projects/erlang/gen_serial/ Code is covered by the EPL, so those of you looking for a Windows driver might want to check the code out. It should remain under active development for quite a while now, as I need it for another project I'm starting to work on. If you run the 8 bit clean test case, you'll need to make sure networking is enabled on your node (-sname). It uses rpc to startup the peer automatically, even if the peer is local. I neglected to note this in the docs, but the test case is pretty easy to read. Feedback would be appreciated. I hope to have 0.2 ready in a few days. -- Shawn. From taj.khattra@REDACTED Wed Feb 25 08:41:50 2004 From: taj.khattra@REDACTED (Taj Khattra) Date: Tue, 24 Feb 2004 23:41:50 -0800 Subject: sends don't block, right? In-Reply-To: <20040225044502.GA10986@spearce.org> References: <20040225034821.GB10730@spearce.org> <20040224201909.2e351791.cpressey@catseye.mine.nu> <20040225044502.GA10986@spearce.org> Message-ID: <20040225074150.GA22940@localhost.localdomain> On Tue, Feb 24, 2004 at 11:45:02PM -0500, Shawn Pearce wrote: > than I, than to run a node for hours trying to fill up main memory until > the node crashes. When you have a full 1 GB of RAM available to the node > its gonna take a while to run that test case I posted. you can start the node with a virtual memory limit. e.g. on my linux box % sh -c 'ulimit -v 8000; exec erl' Erlang (BEAM) emulator version 5.3 [source] [hipe] Eshell V5.3 (abort with ^G) 1> lists:duplicate(100000, abc). Crash dump was written to: erl_crash.dump eheap_alloc: Cannot allocate 785672 bytes of memory (of type "old_heap"). Aborted (core dumped) -taj From francesco@REDACTED Wed Feb 25 08:53:52 2004 From: francesco@REDACTED (Francesco Cesarini) Date: Wed, 25 Feb 2004 07:53:52 +0000 Subject: sends don't block, right? In-Reply-To: <20040225034821.GB10730@spearce.org> References: <20040225034821.GB10730@spearce.org> Message-ID: <403C5490.8080902@erlang-consulting.com> There are design rules (http://www.erlang.se/doc/programming_rules.shtml) to always flush unknown messages, logging the error. I usually go a step further and suggest people make their gen_server code crash through a badmatch if they receive unknown calls and casts, as they are bugs and should not be sent. For handle info, always add a debug printout, as the story is slightly different. Messages for ports closing, nodes going down, possibly expired time-outs, or as I recently discovered, results from asynchronous RPCs, and other junk might appear. Shawn - If you are worried about a blocking parent, you could solve your problem with asynchronous call-backs and time-outs. Cheers, Francesco -- http://www.erlang-consulting.com Shawn Pearce wrote: >Ok, colo(u)r me stupid now (borrowed phrase, sorry!): > >! doesn't block, right? > >If I do something foolish like this: > > never_end() -> > Pid = spawn(fun() -> receive foo -> ok end), > do_loop(Pid). > > do_loop(Pid) -> > Pid ! bar, > io:format("still going, just like the bunny~n", []), > do_loop(Pid). > >will the parent ever stop because the child's message buffer is full? > >Basically, I'm asking if Erlang will let the parent in this case run >the VM out of memory before making the parent freeze. Clearly one should >never write this code, but I'm trying to setup an async-send for my >serial driver that will "never" block the caller, as apposed to the >blocking send which makes sure the data was delivered to the endpoint >before returning. > >The only reason I'm concerned here is the caller could lock up if it >gets blocked and hardware or software flow control breaks down due to >link failure. > >With most serial protocols I wouldn't see the need to buffer more than >a few hundred KB of data, and the port driver already has buffers deep >enough to handle that, so in theory, port_command/2 should never block. >I just want to keep from blocking up the application, if the application >so desires. > > > From vlad_dumitrescu@REDACTED Wed Feb 25 10:42:19 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 25 Feb 2004 10:42:19 +0100 Subject: gen_serial-0.1 release out References: <20040225071939.GA12572@spearce.org> Message-ID: > FWIW, I have a (what appears to be) working serial port driver for > Windows. I plan to have UNIX support within a few days. > > http://www.spearce.org/projects/erlang/gen_serial/ Great! Now I can finally run my Lego Mindstorms robots from Erlang! :-) Oh, there is a typo in gen_serial.erl line 428: Port should be PortRef. regards, Vlad From joe@REDACTED Wed Feb 25 11:45:26 2004 From: joe@REDACTED (Joe Armstrong) Date: Wed, 25 Feb 2004 11:45:26 +0100 (CET) Subject: sends don't block, right? In-Reply-To: <20040225034821.GB10730@spearce.org> Message-ID: On Tue, 24 Feb 2004, Shawn Pearce wrote: > Ok, colo(u)r me stupid now (borrowed phrase, sorry!): > > ! doesn't block, right? > > If I do something foolish like this: > > never_end() -> > Pid = spawn(fun() -> receive foo -> ok end), > do_loop(Pid). > > do_loop(Pid) -> > Pid ! bar, > io:format("still going, just like the bunny~n", []), > do_loop(Pid). > > will the parent ever stop because the child's message buffer is full? > That depends on the relative rates that the produce and consumer run at. If you consume messages faster than you produce them then you will be ok - otherwise you'll be screwed. In the early days of Erlang I used to write a mixture of RPCs and casts pretty much as the problem dictated - occasionally I'd run into buffer overrun problems (such as the kind that would occur in your example) and so I went over to the synced RPC style of programming where buffer overflow can't occur. More recently I have returned to my original style of programming - Asynchronous sends are find - but you need to take a little care to make sure you can't go into infinite send loops (like you program) and that if you are doing a load of asynchronous sends then you interleave the odd RPC to synchronize things again. If you do a whole bundle of asynchronous sends and then an RPC things will get synchronized at the RPC and the buffers should not saturate - this is of course only true between pairs of processes. I now love my !! operator - and program clients with A ! B and Val = A !! B operators I program the servers like this: receive {replyTo, Pid, ReplyAs, Q} -> ... Pid ! {ReplyAs, Val} ... Msg -> ... And don't use any stub routines (horrors). Robert (Virding) first programmed the I/O routines with this replyTo-replyAs style - it's very nice ... Now I don't write interface functions that abstract out the message passing interface. That way I can clearly "see" the message passing. If you use !! at the top level of your code then you can "see" the RPC - my brain goes (RPC this might be slow - take care, and RPC this will synchronize any outstanding asynchronous message) - so I can see what I'm doing. Burying this *inside* a stub function which hides the RPC makes me loose sight of the important fact that we are doing an RPC. If the RPC is "off site" (ie we do an RPC on a remote node) then we have abstracted away from the single most important detail that the programmer should no about. Non-local RPCs cause great performance hits. When I see this in my code: Pid @ Node !! X I think <> with Pid !! X I think <> but X ! Y I thing <> Hiding this essential detail in a stub routine seems to be abstracting away from the one essential detail that we need to know about when writing distributed programs. /Joe > Basically, I'm asking if Erlang will let the parent in this case run > the VM out of memory before making the parent freeze. Clearly one should > never write this code, but I'm trying to setup an async-send for my > serial driver that will "never" block the caller, as apposed to the > blocking send which makes sure the data was delivered to the endpoint > before returning. > > The only reason I'm concerned here is the caller could lock up if it > gets blocked and hardware or software flow control breaks down due to > link failure. > > With most serial protocols I wouldn't see the need to buffer more than > a few hundred KB of data, and the port driver already has buffers deep > enough to handle that, so in theory, port_command/2 should never block. > I just want to keep from blocking up the application, if the application > so desires. > > From vlad_dumitrescu@REDACTED Wed Feb 25 13:52:04 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 25 Feb 2004 13:52:04 +0100 Subject: sends don't block, right? References: Message-ID: From: "Joe Armstrong" > If you use !! at the top level of your code then you can "see" the > RPC - my brain goes (RPC this might be slow - take care, and RPC this > will synchronize any outstanding asynchronous message) - so I can see > what I'm doing. You make a very nice argument for the !! operator, while explaining some basic Erlang philosophy. If only it was easy to specify timeouts, I'd be sold! /Vlad From joe@REDACTED Wed Feb 25 14:48:58 2004 From: joe@REDACTED (Joe Armstrong) Date: Wed, 25 Feb 2004 14:48:58 +0100 (CET) Subject: sends don't block, right? In-Reply-To: Message-ID: On Wed, 25 Feb 2004, Vlad Dumitrescu wrote: > From: "Joe Armstrong" > > If you use !! at the top level of your code then you can "see" the > > RPC - my brain goes (RPC this might be slow - take care, and RPC this > > will synchronize any outstanding asynchronous message) - so I can see > > what I'm doing. > > You make a very nice argument for the !! operator, while explaining some basic > Erlang philosophy. If only it was easy to specify timeouts, I'd be sold! > > /Vlad > I wondered about the following: If we make the following one line addition to erl_parse.yrl: expr_100 -> expr_150 '!' '!' expr_100: {call, line('$1'),{atom, line('$1'), rpc},['$1', '$4']}. Then A !! B just gets expanded into the *local* function rpc(A, B) and the user is free to add their own definition of rcp/2 to the module concerned. So in one module I might say: rpc(Pid, Q) -> Pid ! {replyTo, self(), replyAs, Pid, Q}, receive {Pid, Reply} -> Reply end. In another rpc(Pid, Q) -> Pid ! {self(), Q}, receive {Pid, Reply} -> Reply; after 1000 -> exit(oops) end. In another -include("rpc1.hrl"). In another: rpc(Pid, Q) -> gen_server:call(....) This is more or less how I program - I want all the !!'s to work the same way in a given scope. ie all of then have timeouts or none, etc. /Joe From spearce@REDACTED Wed Feb 25 15:08:30 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 09:08:30 -0500 Subject: sends don't block, right? In-Reply-To: References: Message-ID: <20040225140830.GC12572@spearce.org> Or really alter the language to allow: Pid !! Message after Timeout -> n end. Yuck. I can't believe I just wrote that pile of garbage. Never mind, VERY bad idea. I'm sold on the local RPC function. Have at it they-who-maintain-the-compiler. Joe Armstrong wrote: > > On Wed, 25 Feb 2004, Vlad Dumitrescu wrote: > > > From: "Joe Armstrong" > > > If you use !! at the top level of your code then you can "see" the > > > RPC - my brain goes (RPC this might be slow - take care, and RPC this > > > will synchronize any outstanding asynchronous message) - so I can see > > > what I'm doing. > > > > You make a very nice argument for the !! operator, while explaining some basic > > Erlang philosophy. If only it was easy to specify timeouts, I'd be sold! > > > > /Vlad > > > > I wondered about the following: > > If we make the following one line addition to erl_parse.yrl: > > expr_100 -> expr_150 '!' '!' expr_100: > {call, line('$1'),{atom, line('$1'), rpc},['$1', '$4']}. > > Then A !! B just gets expanded into the *local* function rpc(A, B) > and the user is free to add their own definition of rcp/2 to the > module concerned. > > So in one module I might say: > > rpc(Pid, Q) -> > Pid ! {replyTo, self(), replyAs, Pid, Q}, > receive > {Pid, Reply} -> > Reply > end. > > In another > > rpc(Pid, Q) -> > Pid ! {self(), Q}, > receive > {Pid, Reply} -> > Reply; > after 1000 -> > exit(oops) > end. > > In another > > -include("rpc1.hrl"). > > In another: > > rpc(Pid, Q) -> > gen_server:call(....) > > This is more or less how I program - I want all the !!'s to work the > same way in a given scope. ie all of then have timeouts or none, etc. > > /Joe > -- Shawn. Fortune's Real-Life Courtroom Quote #3: Q: When he went, had you gone and had she, if she wanted to and were able, for the time being excluding all the restraints on her not to go, gone also, would he have brought you, meaning you and she, with him to the station? MR. BROOKS: Objection. That question should be taken out and shot. From vlad_dumitrescu@REDACTED Wed Feb 25 15:12:47 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 25 Feb 2004 15:12:47 +0100 Subject: sends don't block, right? References: Message-ID: From: "Joe Armstrong" > If we make the following one line addition to erl_parse.yrl: > > expr_100 -> expr_150 '!' '!' expr_100: > {call, line('$1'),{atom, line('$1'), rpc},['$1', '$4']}. > > Then A !! B just gets expanded into the *local* function rpc(A, B) > and the user is free to add their own definition of rcp/2 to the > module concerned. Mmm, yes, but IMHO this makes the semantics of !! not so easy to grasp. Having a local definition helps (because of the locality) but one still has to check what it means. /Vlad From spearce@REDACTED Wed Feb 25 15:16:11 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 09:16:11 -0500 Subject: sends don't block, right? In-Reply-To: References: <20040225034821.GB10730@spearce.org> Message-ID: <20040225141611.GD12572@spearce.org> Joe, thanks for a nicely written reply. So long as the developer is programming using send/recv (like with gen_tcp), they will most likely synchronize with the other process, and consequently ensure the message queues are emptied at frequent intervals. Really I was just a little concerned about the caller blocking up due to buffers being jammed everywhere except on the target process' message queue, so that the caller could do: gen_serial:send(Port, << ... >>), case gen_serial:recv(Port, 8, 3000) of {ok, Data} -> ... {error, timeout} -> error_logger:error_report(...) end. and be sure that the recv call is where they will block. From what everyone has told me, this is basically what will happen. You make a good arguement for !!, but do you really mean to suggest that the above should be written as: Port ! {send, << ... >>}, case Port !! {recv, 8, 3000} of {ok, Data} -> ... {error, timeout} -> error_logger:error_report(...) end. ? I'm quite sure I find the syntax ugly, at least in this case. :) But then again, this is like a file IO process, it shouldn't be seen by the user; or the user shouldn't know its there. If my driver was a linked-in driver I wouldn't even need the process at all. Joe Armstrong wrote: > Asynchronous sends are find - but you need to take a little care to > make sure you can't go into infinite send loops (like you program) and > that if you are doing a load of asynchronous sends then you interleave > the odd RPC to synchronize things again. > > If you do a whole bundle of asynchronous sends and then an RPC > things will get synchronized at the RPC and the buffers should not > saturate - this is of course only true between pairs of processes. > > I now love my !! operator - and program clients with > > A ! B and > Val = A !! B > > operators > > I program the servers like this: > > receive > {replyTo, Pid, ReplyAs, Q} -> > ... > Pid ! {ReplyAs, Val} > ... > Msg -> > ... > > And don't use any stub routines (horrors). > > Robert (Virding) first programmed the I/O routines with this > replyTo-replyAs style - it's very nice ... > > Now I don't write interface functions that abstract out the message > passing interface. That way I can clearly "see" the message passing. > > If you use !! at the top level of your code then you can "see" the > RPC - my brain goes (RPC this might be slow - take care, and RPC this > will synchronize any outstanding asynchronous message) - so I can see > what I'm doing. > > Burying this *inside* a stub function which hides the RPC makes me > loose sight of the important fact that we are doing an RPC. If the RPC > is "off site" (ie we do an RPC on a remote node) then we have > abstracted away from the single most important detail that the > programmer should no about. > > Non-local RPCs cause great performance hits. > > When I see this in my code: > > Pid @ Node !! X > > I think <> > > with > > Pid !! X > > I think <> > > but > > X ! Y > > I thing <> > > Hiding this essential detail in a stub routine seems to be > abstracting away from the one essential detail that we need to know > about when writing distributed programs. -- Shawn. I had no shoes and I pitied myself. Then I met a man who had no feet, so I took his shoes. -- Dave Barry From ulf.wiger@REDACTED Wed Feb 25 15:17:17 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Wed, 25 Feb 2004 15:17:17 +0100 Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Tue, 24 Feb 2004 18:22:29 +0100, Ulf Wiger wrote: > Since this is going well, I press on with feature requests. (: Is there some profound reason why Variable '::' Type isn't allowed on the right-hand side of a function spec? I can write Variable or Type, but not Variable::Type. I'd like to be able to write %% @spec handle_call(Request::request(), From::from(), State::state()) -> %% {reply, Reply::reply(), NewState::state()} so that I can refer to NewState in the following @doc, but this is not allowed. I can give it a name or a type, but not both. Vexing. /Uffe -- Ulf Wiger, Senior System Architect EAB/UPD/S This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From spearce@REDACTED Wed Feb 25 15:25:20 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 09:25:20 -0500 Subject: sends don't block, right? In-Reply-To: <403C5490.8080902@erlang-consulting.com> References: <20040225034821.GB10730@spearce.org> <403C5490.8080902@erlang-consulting.com> Message-ID: <20040225142520.GE12572@spearce.org> And all of these are good rules, and my poorly written example to find out worst-case behavior really breaks them. :-) My real code of course follows these. Only I usually reply back to the caller in a gen_server when the call is invalid/unsupported. This way the caller gets {error, {badcall, Call}} rather than a server crashing. I mean, what if a programmer does something stupid in a client like: Server = ..., OtherServer = ..., case server_api:lock(OtherServer) of ok -> case other_server_api:lock(Server) of ok -> ... ? Do we really want both servers to crash because a client application mixed up the pids? Usually not. But usually the caller will crash due to a badmatch: ok = server_api:lock(OtherServer), ok = other_server_api:lock(Server) and wham! The client dies, as it has the error, and the server stays up, as it is otherwise healthy. I was worried about the parent blocking because lets say that the serial port has stopped being able to transmit data out the serial line. The OS buffer will fill up, and then the port driver buffer will fill, and then the OS pipe buffer (between the node and the port driver) will fill, and then the node's output biffer will fill.. and any process using port_command/2 will block (port busy). But I can't use a timeout with port_command/2. But I can by doing this: user: Server ! {send, Data}, Server ! {recv, self(), 8}, receive {reply, Data} -> Data after 30 * 1000 -> exit(timeout) end server: loop(P) -> receive {send, D} -> port_command(P, D), loop(P); {recv, From, L) -> port_command(P, ...), receive {P, ..., Data} -> From ! {reply, Data} end, loop(P) end. and be certain that the user will not block until the receive call, where it can handle the timeout. Oh sure, the server will be frozen in the port_command when handling {send, D}, but the client will just buffer up {recv, F, L} in the server message queue, block in the receive, wakeup from the timeout, crash (as the port is all screwed up now) and because I always link the user and the server (spawn_link is my friend) the port will get killed. I was just worried if the client decided to send say 10 chunks of data, and then block in recv that the buffering wasn't going to be an issue. From what I've been told, I'm perfectly safe in that. This is a serial port after all, it can barely do 256,000 bits per second. :-) Francesco Cesarini wrote: > There are design rules > (http://www.erlang.se/doc/programming_rules.shtml) to always flush > unknown messages, logging the error. I usually go a step further and > suggest people make their gen_server code crash through a badmatch if > they receive unknown calls and casts, as they are bugs and should not be > sent. For handle info, always add a debug printout, as the story is > slightly different. Messages for ports closing, nodes going down, > possibly expired time-outs, or as I recently discovered, results from > asynchronous RPCs, and other junk might appear. > > Shawn - If you are worried about a blocking parent, you could solve your > problem with asynchronous call-backs and time-outs. -- Shawn. Death. Destruction. Disease. Horror. That's what war is all about. That's what makes it a thing to be avoided. -- Kirk, "A Taste of Armageddon", stardate 3193.0 From richardc@REDACTED Wed Feb 25 15:46:14 2004 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 25 Feb 2004 15:46:14 +0100 (MET) Subject: The New and Improved edoc In-Reply-To: References: Message-ID: On Wed, 25 Feb 2004, Ulf Wiger wrote: > Is there some profound reason why Variable '::' Type isn't allowed on > the right-hand side of a function spec? I can write Variable or Type, > but not Variable::Type. Yes - the reason is that the whole of the right-hand side (after the '->') is a single type expression, just like each separate Type in 'Variable::Type'. The signature says "the parameters of this function have these names and these types, and the return value has that type". > I'd like to be able to write > > %% @spec handle_call(Request::request(), From::from(), State::state()) -> > %% {reply, Reply::reply(), NewState::state()} > > so that I can refer to NewState in the following @doc, but this is not > allowed. I can give it a name or a type, but not both. Vexing. The way to do that today is of course: %% @spec handle_call(Request::request(), From::from(), State::state()) -> %% {reply, Reply, NewState} %% Reply = reply() %% NewState = state() but I know that this is something that has many people confused and/or vexed. If one would regard 'Name::...' as metadata in a type expression, without any further meaning, then I think it works. I'll see if it can be added. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From vlad_dumitrescu@REDACTED Wed Feb 25 15:47:28 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 25 Feb 2004 15:47:28 +0100 Subject: sends don't block, right? References: <20040225034821.GB10730@spearce.org> <403C5490.8080902@erlang-consulting.com> <20040225142520.GE12572@spearce.org> Message-ID: > This is a serial port after all, it can barely do 256,000 bits per second. :-) Oh, you mean it doesn't work with USB serial ports? ;-) /Vlad From vances@REDACTED Wed Feb 25 19:42:47 2004 From: vances@REDACTED (Vance Shipley) Date: Wed, 25 Feb 2004 13:42:47 -0500 Subject: sends don't block, right? In-Reply-To: <20040225142520.GE12572@spearce.org> References: <20040225034821.GB10730@spearce.org> <403C5490.8080902@erlang-consulting.com> <20040225142520.GE12572@spearce.org> Message-ID: <20040225184247.GB50606@frogman.motivity.ca> On Wed, Feb 25, 2004 at 09:25:20AM -0500, Shawn Pearce wrote: } } ... I usually reply back to the caller in a gen_server when the } call is invalid/unsupported. This way the caller gets } {error, {badcall, Call}} rather than a server } crashing. I } mean, what if a programmer does something stupid in a client I think this is right. The philosphy of crashing on programming errors is a good one however one needs to think about who the programmer is when building APIs. The intent of providing an API is that the client programmer doesn't have to understand anything other than the API. He doesn't want to have to debug the service he is using therefore a crash report isn't useful to him. I consider API interfaces to be slightly unreliable so do some amount of error checking on them. I like to do things like: foo(Integer) when is_integer(Integer) -> 1 + Integer. Which follows the let it crash and make it crash early philosophy. This causes the right sort of report: 1> t:foo(a). =ERROR REPORT==== 25-Feb-2004::13:27:24 === Error in process <0.26.0> with exit value: {function_clause,[{t,foo,[a]},{erl_eval,do_apply,5},{shell,eval_loop,2}]} ** exited: {function_clause,[{t,foo,[a]}, {erl_eval,do_apply,5}, {shell,eval_loop,2}]} ** This tells the client programmer what he needs to know; that there is no matching function clause for foo(a). Without the guard we get: =ERROR REPORT==== 25-Feb-2004::13:26:54 === Error in process <0.24.0> with exit value: {badarith,[{t,foo,1},{shell,eval_loop,2}]} ** exited: {badarith,[{t,foo,1},{shell,eval_loop,2}]} ** The client programmer scratches his head wondering why he's doing arithmetic. This exposes the internals of the service unecessarily. -Vance From carsten@REDACTED Wed Feb 25 22:33:40 2004 From: carsten@REDACTED (Carsten Schultz) Date: Wed, 25 Feb 2004 22:33:40 +0100 Subject: Erlang external term format In-Reply-To: References: <20040224115846.GC23238@penne.localnet> Message-ID: <20040225213339.GM23238@penne.localnet> On Tue, Feb 24, 2004 at 02:31:24PM +0100, Vlad Dumitrescu wrote: > look into erts/emulator/internal_doc in the sources. That was very helpful, thanks again. I have written a (partial) implementation of it in Haskell, it works and it is fun. Now, the Haskell programs my Yaws script call can send back Erlang terms :-) (The FLOAT_EXT part could use some clarification.) Is the atom cache described in the above document used anywhere? Not in binary_to_term, it seems, at least if I understand it correctly. It's a pity, it looked like a good idea. Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From ok@REDACTED Thu Feb 26 00:52:58 2004 From: ok@REDACTED (Richard A. O'Keefe) Date: Thu, 26 Feb 2004 12:52:58 +1300 (NZDT) Subject: sends don't block, right? Message-ID: <200402252352.i1PNqwmn287593@atlas.otago.ac.nz> Shawn Pearce wrote: Nah. I'm not that worried about it. It was easier to email the list and get a response from someone like yourself who knows Erlang better than I, than to run a node for hours trying to fill up main memory until the node crashes. When you have a full 1 GB of RAM available to the node its gonna take a while to run that test case I posted. In UNIX, it's dead easy and dead quick to find out what happens when a process runs out of memory. Use % sh % ulimit -v N % your-program % exit where N is the number of kilobytes you want to limit the program's virtual memory to. See also the -d and -s options. In the C shell, use limit/datasize/stacksize/memorysize instead of ulimit/-d/-s/-v. A great way of checking whether C programs check the result of malloc()... Set the limit to something smallish, and watch the wreckage fly. From kent@REDACTED Thu Feb 26 01:31:11 2004 From: kent@REDACTED (Kent Boortz) Date: 26 Feb 2004 01:31:11 +0100 Subject: Erlang external term format In-Reply-To: <20040225213339.GM23238@penne.localnet> References: <20040224115846.GC23238@penne.localnet> <20040225213339.GM23238@penne.localnet> Message-ID: Carsten Schultz writes: > > look into erts/emulator/internal_doc in the sources. > > That was very helpful, thanks again. I have written a (partial) > implementation of it in Haskell, it works and it is fun. Now, the > Haskell programs my Yaws script call can send back Erlang terms :-) > (The FLOAT_EXT part could use some clarification.) Nice. Yes the document needs some improvements. Note that it is in some cases possible to encode the same term in different ways. For example an Erlang integer is not necessarily encoded into the most compact external representation. An INTEGER_EXT can hold a 32 bit integer but currently the emulator and erl_interface only use it for encoding integers that fits into 28 bits (for historical reasons I think). > Is the atom cache described in the above document used anywhere? Not > in binary_to_term, it seems, at least if I understand it correctly. > It's a pity, it looked like a good idea. It is used encoding terms in the distribution protocol between two nodes that agree on using it. Look in erts/emulator/beam/dist.c erts/emulator/beam/external.c kent This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From cpressey@REDACTED Thu Feb 26 01:38:23 2004 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 25 Feb 2004 16:38:23 -0800 Subject: sends don't block, right? In-Reply-To: <20040225044502.GA10986@spearce.org> References: <20040225034821.GB10730@spearce.org> <20040224201909.2e351791.cpressey@catseye.mine.nu> <20040225044502.GA10986@spearce.org> Message-ID: <20040225163823.29f42ca0.cpressey@catseye.mine.nu> On Tue, 24 Feb 2004 23:45:02 -0500 Shawn Pearce wrote: > Chris Pressey wrote: > > On Tue, 24 Feb 2004 22:48:21 -0500 > > Shawn Pearce wrote: > > > > > Basically, I'm asking if Erlang will let the parent in this case > > > run the VM out of memory before making the parent freeze. > > > > Yes, exactly that. > > Excellent, that's what I had thought, but its been a while since I > had last read that fact and/or proved it to myself by reading that > section of the emulator source code. > > Not that I'd ever condone taking a node down like this. But the fact > that Erlang will grow the buffers as needed is what I'd expect. I'd much, much, MUCH rather it just kill the receiving process or (better) discard the message after a receive buffer limit is reached, than taking down the entire node, though. > Nah. I'm not that worried about it. It was easier to email the list > and get a response from someone like yourself who knows Erlang better > than I Used it more in terms of sheer hours, perhaps; know it better, probably not -- I'm still essentially mystified by OTP and erl_interface... btw, I agree 100% (maybe 1000%) with Joe on the idea that hiding IPC stuff inside wrapper functions is just plain *wrongheaded*. Yes, abstraction is good, but no, a function makes a *horrible* abstraction for IPC -- especially in a "functional" language where functions aren't supposed to have side-effects :) -Chris From spearce@REDACTED Thu Feb 26 02:43:13 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 20:43:13 -0500 Subject: sends don't block, right? In-Reply-To: References: <20040225034821.GB10730@spearce.org> <403C5490.8080902@erlang-consulting.com> <20040225142520.GE12572@spearce.org> Message-ID: <20040226014313.GF12572@spearce.org> Vlad Dumitrescu wrote: > > This is a serial port after all, it can barely do 256,000 bits per second. :-) > > Oh, you mean it doesn't work with USB serial ports? ;-) Err, Uhm, well, its never been tested with them. It should work with those USB to RS-232 converter boxes if that's what you mean. But it might not, as that's a different serial port driver to Windows, and that driver might not behave as nice as the standard UART one does. Perhaps its also possible to use this code to talk to other USB devices, but I doubt it. But I'd like to get that supported in perhaps a gen_usb some day. :) -- Shawn. Anyone who goes to a psychiatrist ought to have his head examined. -- Samuel Goldwyn From spearce@REDACTED Thu Feb 26 03:07:08 2004 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 25 Feb 2004 21:07:08 -0500 Subject: sends don't block, right? In-Reply-To: <20040225163823.29f42ca0.cpressey@catseye.mine.nu> References: <20040225034821.GB10730@spearce.org> <20040224201909.2e351791.cpressey@catseye.mine.nu> <20040225044502.GA10986@spearce.org> <20040225163823.29f42ca0.cpressey@catseye.mine.nu> Message-ID: <20040226020708.GH12572@spearce.org> Chris Pressey wrote: > I'd much, much, MUCH rather it just kill the receiving process or > (better) discard the message after a receive buffer limit is reached, > than taking down the entire node, though. I agree. If the node cannot give memory to a process for its heap or its message queue, the process should be immediately killed with the reason 'enomem'. This kill should not be trappable by any catch expressions either. If the developer/designer/whatever doesn't want the process to just vanish in low memory conditions they should setup a proper supervision tree. A good supervisor won't allocate memory, and thus should be able to have enough free temporary space to get the 'EXIT' message of the child, realize its an enomem error, and handle it somehow. It may just be enough to restart the process as the process may have just been leaking a ton of memory (by stuffing things into its dictionary for example). > Used it more in terms of sheer hours, perhaps; know it better, probably > not -- I'm still essentially mystified by OTP and erl_interface... Heh. I don't think there's many out there who really do know OTP. One thing I pick up well is low-level guts of almost anything.. so I feel like I have a decent grasp on how much of OTP works, but certainly cannot claim to know it as well as many of the folks here. erl_interface isn't bad either.. pretty simple actually. Which is a pleasure compared to some of the other higher-level languages and their interfaces. > btw, I agree 100% (maybe 1000%) with Joe on the idea that hiding IPC > stuff inside wrapper functions is just plain *wrongheaded*. Yes, > abstraction is good, but no, a function makes a *horrible* abstraction > for IPC -- especially in a "functional" language where functions aren't > supposed to have side-effects :) Yea, I've become convinced of this now too. So I'll just keep asking, when will !! become part of the langauge? :) I'd have to suggest that if !! is added the way Joe is suggesting (use a local rpc/2 function to do the send/receive operations) that the compiler either automatically generate an rpc/2 function if one is not supplied, or that it give a very good error message indicating that the rpc/2 function is missing, what it needs to do, and why the compiler is requesting it. -- Shawn. From ulf.wiger@REDACTED Thu Feb 26 07:53:42 2004 From: ulf.wiger@REDACTED (Ulf Wiger) Date: Thu, 26 Feb 2004 07:53:42 +0100 Subject: sends don't block, right? In-Reply-To: <20040226020708.GH12572@spearce.org> References: <20040225034821.GB10730@spearce.org> <20040224201909.2e351791.cpressey@catseye.mine.nu> <20040225044502.GA10986@spearce.org> <20040225163823.29f42ca0.cpressey@catseye.mine.nu> <20040226020708.GH12572@spearce.org> Message-ID: On Wed, 25 Feb 2004 21:07:08 -0500, Shawn Pearce wrote: > Chris Pressey wrote: >> btw, I agree 100% (maybe 1000%) with Joe on the idea that hiding IPC >> stuff inside wrapper functions is just plain *wrongheaded*. Yes, >> abstraction is good, but no, a function makes a *horrible* abstraction >> for IPC -- especially in a "functional" language where functions aren't >> supposed to have side-effects :) > > Yea, I've become convinced of this now too. I agree. I'd like to be able to see message passing more clearly. It will still be possible to hide it behind function calls, just like today, since !! is only syntactic sugar. One problem is that it's more difficult to trace IPC dependencies. We have xref for finding function call dependencies between modules, and at AXD 301, we have CCviewer which provides hypertext linking with forward and backward references (basically, Emacs tags and Distel do this too.) But what do you do to follow the trail of a message while reading source code? It can be arbitrarily difficult. I've spent some time pondering the problem trying to add something to CCviewer, but it's not easy. And if you can't tell a tool where to jump, humans will have more difficulty as well. I'd like to see some invention here as well. This would strengthen Joe's case that we could focus more on message passing and RPCs. > So I'll just keep asking, when will !! become part of the langauge? :) > > I'd have to suggest that if !! is added the way Joe is suggesting > (use a local rpc/2 function to do the send/receive operations) that the > compiler either automatically generate an rpc/2 function if one is not > supplied, or that it give a very good error message indicating that > the rpc/2 function is missing, what it needs to do, and why the > compiler is requesting it. Or add an -import(gen, [rpc/2]). Don't know if this should be done automatically - but probably. gen:rpc/2 should use basically the same semantics as gen:call/2 (that would mean a default 5 second timeout), and there should also be a gen:rpc/3, which one could easily use by adding rpc(Server, Request) -> gen:rpc(Server, Request, 17000). e.g. for a 17 second timeout. /Uffe -- Ulf Wiger From bjarne@REDACTED Thu Feb 26 09:44:31 2004 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Thu, 26 Feb 2004 09:44:31 +0100 Subject: Erlang external term format References: <20040224115846.GC23238@penne.localnet> <20040225213339.GM23238@penne.localnet> Message-ID: <001701c3fc44$c1944040$b60a69d4@segeltorp> Stop sending mails with no text but only attachments. They are sure to contain viruses. Bjarne ----- Original Message ----- From: "Carsten Schultz" To: "Erlang users' list" Sent: Wednesday, February 25, 2004 10:33 PM Subject: Re: Erlang external term format From thomasl_erlang@REDACTED Thu Feb 26 10:57:56 2004 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Thu, 26 Feb 2004 01:57:56 -0800 (PST) Subject: sends don't block, right? In-Reply-To: <20040225163823.29f42ca0.cpressey@catseye.mine.nu> Message-ID: <20040226095756.15625.qmail@web41904.mail.yahoo.com> --- Chris Pressey wrote: > I'd much, much, MUCH rather it just kill the > receiving process or > (better) discard the message after a receive buffer > limit is reached, > than taking down the entire node, though. Yes ... I think Safe Erlang had some support for this (but did it ever get implemented?). Though when I fretted about similar issues, Per Bergqvist told me I could also just use several nodes and limit the size of each to get roughly the same effect. (At some extra cost, of course.) This seemed sensible enough. > btw, I agree 100% (maybe 1000%) with Joe on the idea > that hiding IPC > stuff inside wrapper functions is just plain > *wrongheaded*. Yes, > abstraction is good, but no, a function makes a > *horrible* abstraction > for IPC No more rpc:call, gen_server:call or gen_tcp:send then? I agree that encapsulation and performance make uneasy bedfellows, but I would dearly like to have some way to abstract certain things. > -- especially in a "functional" language > where functions aren't > supposed to have side-effects :) Very true. The cure seems worse than the disease, though :-) Is there a better way than either? Best, Thomas __________________________________ Do you Yahoo!? Get better spam protection with Yahoo! Mail. http://antispam.yahoo.com/tools From chris.williams@REDACTED Thu Feb 26 11:00:59 2004 From: chris.williams@REDACTED (Chris Williams) Date: Thu, 26 Feb 2004 11:00:59 +0100 (MET) Subject: Megaco over UDP/IP? Message-ID: Hi Has any one used the Erlang Megaco(H.248) stack for transport over UDP/IP? If so did you have any problems running Megaco over UDP/IP? We here at AXD have run Megaco over ATM, SCTP/IP and TCP/IP and considering to run Megaco over UDP/IP for certain Access Gateways. Running Megaco over ATM and SCTP works fine..... //Chris This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From joe@REDACTED Thu Feb 26 11:12:54 2004 From: joe@REDACTED (Joe Armstrong) Date: Thu, 26 Feb 2004 11:12:54 +0100 (CET) Subject: Maps anybody Message-ID: Does anybody know anything about digital maps? I would like an outline map of the world - just a list of vectors. Also, can anybody know the answers to the following questions? - what are the most common formats for digital maps? - where can I obtain detailed free world/regional maps? - where are the formats specified - is there any Erlang code to parse/transform/plot map data? Why do I want this? - I've joined Planet lab (http://www.planet-lab.org/) and soon Erlang will be running on all planet lab nodes - and I'd like graph the performance of the system on a world map. /Joe From vlad_dumitrescu@REDACTED Thu Feb 26 11:55:42 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 26 Feb 2004 11:55:42 +0100 Subject: Maps anybody References: Message-ID: > I would like an outline map of the world - just a list of vectors. A good place to start searcing would be http://www.giscentrum.lu.se/english/geodataPublic.htm#Varldskartor /Vlad From chris.williams@REDACTED Thu Feb 26 12:04:02 2004 From: chris.williams@REDACTED (Chris Williams) Date: Thu, 26 Feb 2004 12:04:02 +0100 (MET) Subject: Maps anybody In-Reply-To: Message-ID: > - what are the most common formats for digital maps? There are quite a few depending on company delivering them ;-( Navigation systems(Digital charts etc..) are usably compliant to a system called ECDIS defined by IMO(International Maritime organization) http://www.imo.org/ > - where can I obtain detailed free world/regional maps? Kazza is quite a good place for finding navigational charts ;-) Sorry to say I do not know if you can find world maps there ;-( //Chris On Thu, 26 Feb 2004, Joe Armstrong wrote: > > Does anybody know anything about digital maps? > > I would like an outline map of the world - just a list of vectors. > > Also, can anybody know the answers to the following questions? > > - what are the most common formats for digital maps? > - where can I obtain detailed free world/regional maps? > - where are the formats specified > - is there any Erlang code to parse/transform/plot map data? > > Why do I want this? - I've joined Planet lab > (http://www.planet-lab.org/) and soon Erlang will be running on all > planet lab nodes - and I'd like graph the performance of the system on > a world map. > > /Joe > > This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From gordon.guthrie@REDACTED Thu Feb 26 12:22:30 2004 From: gordon.guthrie@REDACTED (Gordon Guthrie, BTP, BT, SE) Date: Thu, 26 Feb 2004 11:22:30 -0000 Subject: Maps anybody Message-ID: <23659D76043CD7119EF400805FBE61F201ACE095@SENMAIL> Joe Armstrong wrote: > Does anybody know anything about digital maps? For my sins, yes I do... > I would like an outline map of the world - just a list of vectors. The best known source for 'free' GIS stuff is the GRASS site, the open source GIS system which can be found at: http://www.geog.uni-hannover.de/grass/ And its free data is at: http://www.geog.uni-hannover.de/grass/data.html There is also this compendium of free gis stuff: http://www.freegis.org/index.en.html With free data at: http://www.freegis.org/geo-data.en.html > Also, can anybody know the answers to the following questions? > > - what are the most common formats for digital maps? > - where can I obtain detailed free world/regional maps? > - where are the formats specified > - is there any Erlang code to parse/transform/plot map data? What maps I have bought have just been small urban A-Z type stuff, I just read the projection info off the CD, configure my geopoint info appropriately and then forget all the mercator/peters/projection/elliptical/headache stuff I'm afraid... You should be able to find the 'hardcore'' technical mapping stuff you want somewhere on these sites - better you than me ;-> Gordon ______________________________________________________________________ Scottish Enterprise Network http://www.scottish-enterprise.com Address & Contact Numbers 150 Broomielaw 5 Atlantic Quay Glasgow G2 8LU. Tel: +44 (0)141 248 2700. Fax: +44 (0)141 221 3217 message is sent in confidence for the addressee only. It may contain legally privileged information. The contents are not to be disclosed to anyone other than the addressee. Unauthorised recipients are requested to preserve this confidentiality and to advise the sender immediately of any error in transmission. From erlang@REDACTED Thu Feb 26 13:22:09 2004 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 26 Feb 2004 12:22:09 +0000 Subject: Megaco over UDP/IP? In-Reply-To: References: Message-ID: <20040226122209.31d9b5fd.erlang@manderp.freeserve.co.uk> Hi Chris I have, and I've encountered no problems. I've even found that there is a significant performance advantage when using UDP instead of TCP. The Megaco protocol handles retransmission, and makes TCP connection oriented transport somewhat redundant, hence the performance gain with UDP. However there may be a need to use TCP if the megaco transaction packets become larger than the MTU. Pete. On Thu, 26 Feb 2004 11:00:59 +0100 (MET) Chris Williams wrote: > Hi > Has any one used the Erlang Megaco(H.248) stack for > transport over UDP/IP? > If so did you have any problems running Megaco over UDP/IP? > > We here at AXD have run Megaco over ATM, SCTP/IP and TCP/IP > and considering to run Megaco over UDP/IP for certain > Access Gateways. > > Running Megaco over ATM and SCTP works fine..... > //Chris > > > This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. > > E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. > -- "The Tao of Programming flows far away and returns on the wind of morning." From vlad_dumitrescu@REDACTED Thu Feb 26 14:32:15 2004 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 26 Feb 2004 14:32:15 +0100 Subject: Maps anybody References: Message-ID: Hi, If you find some data and need to read it, there is a library for ArcInfo (E00) files at http://avce00.maptools.org/ regards, /Vlad From cyberlync@REDACTED Thu Feb 26 15:44:58 2004 From: cyberlync@REDACTED (Eric Merritt) Date: Thu, 26 Feb 2004 06:44:58 -0800 (PST) Subject: Maps anybody In-Reply-To: Message-ID: <20040226144458.43548.qmail@web40801.mail.yahoo.com> Joe, I don't know if its what youre looking for but GIS is pretty popular for storing geographic information. The nice thing about GIS is that it stores the information in a relational database. This means that all the usual sql stuff works and all you have to do is learn the GIS specific syntax. Both postgresql and mysql support gis information. Postgresql GIS support is supposedly better, but its much harder to install. MySqls is less robust but its built in. --- Joe Armstrong wrote: > > Does anybody know anything about digital maps? > > I would like an outline map of the world - just a > list of vectors. > > Also, can anybody know the answers to the > following questions? > > - what are the most common formats for digital > maps? > - where can I obtain detailed free world/regional > maps? > - where are the formats specified > - is there any Erlang code to parse/transform/plot > map data? > > Why do I want this? - I've > joined Planet lab > (http://www.planet-lab.org/) and soon Erlang will > be running on all > planet lab nodes - and I'd like graph the > performance of the system on > a world map. > > /Joe > > __________________________________ Do you Yahoo!? Get better spam protection with Yahoo! Mail. http://antispam.yahoo.com/tools From jay@REDACTED Thu Feb 26 16:42:20 2004 From: jay@REDACTED (Jay Nelson) Date: Thu, 26 Feb 2004 07:42:20 -0800 Subject: Maps anybody Message-ID: <4.2.2.20040226073744.00a23d20@duomark.com> > I would like an outline map of the world - just a > list of vectors. CIA World Data Bank II was a project in the 80's to develop outline maps, borders and geographical elements. The data is freely available. Details at: http://www.evl.uic.edu/pape/data/WDB/ and http://www.246.dk/ciaworld.html From erlang@REDACTED Thu Feb 26 21:32:04 2004 From: erlang@REDACTED (Inswitch Solutions - Erlang Evaluation) Date: Thu, 26 Feb 2004 17:32:04 -0300 Subject: Crash dump location Message-ID: <011601c3fca7$9a56bea0$1e00a8c0@design> Hi! Does anyone know if I can run my Erlang applications from a CD? For example how can I tell ERTS to save crash_dumps file to another location? thanks, Eduardo Figoli INSwitch Solutions -------------- next part -------------- An HTML attachment was scrubbed... URL: From kent@REDACTED Thu Feb 26 23:06:01 2004 From: kent@REDACTED (Kent Boortz) Date: 26 Feb 2004 23:06:01 +0100 Subject: Crash dump location In-Reply-To: <011601c3fca7$9a56bea0$1e00a8c0@design> References: <011601c3fca7$9a56bea0$1e00a8c0@design> Message-ID: "Inswitch Solutions - Erlang Evaluation" writes: > Does anyone know if I can run my Erlang applications from a CD? > For example how can I tell ERTS to save crash_dumps file to another location? You can set the ERL_CRASH_DUMP environment variable to point out the file to write the dump into, kent This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you. E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof. From peter.olin@REDACTED Sat Feb 28 13:52:33 2004 From: peter.olin@REDACTED (Peter Olin) Date: Sat, 28 Feb 2004 13:52:33 +0100 Subject: Xref visualization Message-ID: <6.0.1.1.2.20040228134937.01c59f28@127.0.0.1> Hi all! I'm trying to understand the dependencies between a bunch of modules that someone else wrote. The new xref tool looks good, but I can't find any tool for visualizing the dependendcies between modules/functions. As I recall it, there used to exist a thing that showed arrows and such. Do you know of any such tool? Kind regards, Peter Olin From klacke@REDACTED Sat Feb 28 18:01:39 2004 From: klacke@REDACTED (klacke@REDACTED) Date: Sat, 28 Feb 2004 18:01:39 +0100 Subject: Embedded System with Yaws on Windows In-Reply-To: References: <000d01c35e90$412f3420$6400a8c0@ituniv398> <151C7243-5CD9-11D8-A881-000A956D87EE@patternmatched.com> <444709DE-5D25-11D8-A881-000A956D87EE@patternmatched.com> <20040217134236.GA7491@hyber.org> Message-ID: <20040228170139.GA19067@hyber.org> On Wed, Feb 18, 2004 at 11:55:59AM +0200, Rudolph van Graan wrote: > On the topic... Do any of you have working code employed to start Yaws > from code? I.e. like in the exact syntax to use to configure everything > in "yaws.conf" in code? http://yaws.hyber.org/embed.yaws > > The one thing I did note regarding yaws on windows was the fact that if > you want to specify "c:\web" as root-folder in yaws.conf, you have to > specify it as "/web"... This immediately raises the question of how to > specify "D:\web"..? If this is the case, It can certainly be described as a bug. There is quite a lot of code inside yaws which (on purpose) doesn't use the filename:join() function in order to concatenate filenames. filename:join() may be correct, but it sure is slooow. Anyway, as for specifying docroot on d:, that should be a breeze to fix. /klacke -- Claes Wikstrom -- Caps lock is nowhere and http://www.hyber.org -- everything is under control From igouy2@REDACTED Sun Feb 29 01:25:56 2004 From: igouy2@REDACTED (Isaac Gouy) Date: Sat, 28 Feb 2004 16:25:56 -0800 (PST) Subject: Eclipse plugin advances Message-ID: <20040229002556.60111.qmail@web60504.mail.yahoo.com> Maybe you could start off with the idea that the IDE is very separate from an Erlang node - OOVM are playing this game with Eclipse and embedded Smalltalk. www.oovm.com __________________________________ Do you Yahoo!? Get better spam protection with Yahoo! Mail. http://antispam.yahoo.com/tools From cyberlync@REDACTED Sun Feb 29 01:58:19 2004 From: cyberlync@REDACTED (Eric Merritt) Date: Sat, 28 Feb 2004 16:58:19 -0800 (PST) Subject: Eclipse plugin advances In-Reply-To: <20040229002556.60111.qmail@web60504.mail.yahoo.com> Message-ID: <20040229005819.92035.qmail@web40811.mail.yahoo.com> --- Isaac Gouy wrote: > Maybe you could start off with the idea that the IDE > is very separate > from an Erlang node - OOVM are playing this game > with Eclipse and > embedded Smalltalk. I am not sure what you mean. Right now we are making large use of the erlang vm as a serperate entity from eclipse, though eclipse will start one if its not already available. This is the same route distel took, we are following along and sharing much of the back end. > > www.oovm.com > > __________________________________ > Do you Yahoo!? > Get better spam protection with Yahoo! Mail. > http://antispam.yahoo.com/tools __________________________________ Do you Yahoo!? Get better spam protection with Yahoo! Mail. http://antispam.yahoo.com/tools From spearce@REDACTED Sun Feb 29 22:58:11 2004 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 29 Feb 2004 16:58:11 -0500 Subject: running linked-in drivers outside of erts? Message-ID: <20040229215811.GA12906@spearce.org> Ok, so I'm building a whole slew of drivers this week, and I want them to run both in erts, and outside as a port process. Reason is, for early development or environments where I can't have the node crash due to a driver bug, I want the safety of the port process - but other users of the driver, or in some situations, I may want to use a loaded driver for performance/memory/etc. Has anyone thought about writing a driver compatability layer that would offer most of the driver_* APIs, but in an external shell? This would let the a driver written for erl_ddll to be loaded in an external port process. -- Shawn.