Comments on: Labeling the Twisted Bits http://laurentszyster.be/blog/labeling-the-twisted-bits/ Python on Peers Tue, 07 Feb 2012 14:40:38 +0000 http://wordpress.org/?v=1.5.1.3 by: Laurent Szyster http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-1017 Wed, 21 Jun 2006 11:53:08 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-1017 To tds, Oli and other GPL-averts When people start to dismiss a library because of its licence, it's a sure sign that they don't have much else to say about its sources. Anyway, let's make that licencing issue clear. There are three ways to go with the GNU Public Licence: 1. If you want to write free software for a greater good using Allegra sources, the GPL will suite your needs perfectly. That's the GNU way. 2. If you want to make a buck installing or distributing Allegra's applications, you're free to do so as long as you comply with the GPL. That's the Linux distro way. 3. If you want to use Allegra sources to write commercial applications to make a profit, buy a commercial licence. That's the MySQL way. Regards, To tds, Oli and other GPL-averts

When people start to dismiss a library because of its licence, it’s a sure sign that they don’t have much else to say about its sources.

Anyway, let’s make that licencing issue clear.

There are three ways to go with the GNU Public Licence:

1. If you want to write free software for a greater good using Allegra sources, the GPL will suite your needs perfectly. That’s the GNU way.

2. If you want to make a buck installing or distributing Allegra’s applications, you’re free to do so as long as you comply with the GPL. That’s the Linux distro way.

3. If you want to use Allegra sources to write commercial applications to make a profit, buy a commercial licence. That’s the MySQL way.

Regards,

]]>
by: oli http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-1015 Wed, 21 Jun 2006 10:26:01 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-1015 yeah, GPL is really useless for a framework and library. LGPL is much better or just release it as public domain (like web.py) yeah, GPL is really useless for a framework and library. LGPL is much better or just release it as public domain (like web.py)

]]>
by: tds http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-809 Tue, 30 May 2006 08:53:52 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-809 It is possible to write closed source application on Linux. Because it is the base system and not a framework or library. But if I use Allegra it is not possible to write a closed source application. So the only choice is twisted. :-) It is possible to write closed source application on Linux. Because it is the base system and not a framework or library.
But if I use Allegra it is not possible to write a closed source application.
So the only choice is twisted. :-)

]]>
by: Laurent Szyster http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-716 Tue, 23 May 2006 09:01:57 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-716 To tds: >GPL is not usable for most people. You mean all those people that use GNU/Linux? Regards, To tds:

>GPL is not usable for most people.

You mean all those people that use GNU/Linux?

Regards,

]]>
by: tds http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-714 Tue, 23 May 2006 07:50:15 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-714 If Allegra is so amazing why not publish it under a usable licese as MIT or BSD license. GPL is not usable for most people. Use same license as twisted and we will see which one will get a broader acceptance. If Allegra is so amazing why not publish it under a usable licese as MIT or BSD license. GPL is not usable for most people.
Use same license as twisted and we will see which one will get a broader acceptance.

]]>
by: Laurent Szyster http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-712 Mon, 22 May 2006 10:29:47 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-712 To Allen: >>If you want to provide application developers with a network component >object model that can plug in the existing *synchronous* API > >We don’t. Ever. > >This is not what Twisted is for. Interfacing with legacy synchronous libraries is one thing, and Twisted has a pretty good record of doing that. So which way is it. "Never" or "pretty good record of doing that" You can't have it both way, can you? >Enabling people to write applications that makes bad assumptions about concurrency is another, and there’s no support, present or future, for doing that. Not bad assumptions. Stable assumptions. For whole parts of the library - actually for anything that rely on async_net async_chat implementation of readable and writable - there is each time only one assumption to make and it is safe. In handle_read () the protocols and transport are both readable. There is no doubt that a readability condition has been agreed concurrently, evaluated at the same time, from the different state of buffers and the channel's collector stack. And it is certain that there is data to be read from the socket. The dispatcher is ready to read, the socket is ready to be read. Idem for handle_write () or any other event handlers dispatched by handle_read_event () handle_write_event () There is no uncertainty about the readability or writability. When a write event is handled, the channel socket *is* writable and the channel protocol is ready to produce output. When the current producer is stalled, if the output_fifo is empty, the channel will not be writable, excluded from the list of sockets polled. That *when* is an implicit but safe assumption to make, at all times. Without a single line of code. So in Allegra there is no need to call pauseProducing () or startReading () after having tested the I/O state of the FileDescriptor ... at all steps in both transport and protocols. Just push producers, let them stall, set collectors, let them collect. And if your protocol does stall, let him just resume buffer collection, nothing more. If you use async_net, the same assumption holds, but you are expected to make do without stallable producers, just iterables of 8-bit byte strings. This is an alternative for newer, faster, multiplexed and chunked protocols. In any case, the I/O state is allways tested only once, for each run of the loop. Exactly before the sockets are polled for I/O events, not in between. And probably with a smaller effect on performance under load than that mambo-jumbo of readability/writablity tests that litter Twisted. Regards, To Allen:

>>If you want to provide application developers with a network component
>object model that can plug in the existing *synchronous* API
>
>We don’t. Ever.
>
>This is not what Twisted is for. Interfacing with legacy synchronous libraries is one thing, and Twisted has a pretty good record of doing that.

So which way is it. “Never” or “pretty good record of doing that”

You can’t have it both way, can you?

>Enabling people to write applications that makes bad assumptions about concurrency is another, and there’s no support, present or future, for doing that.

Not bad assumptions.

Stable assumptions. For whole parts of the library - actually for anything that rely on async_net async_chat implementation of readable and writable - there is each time only one assumption to make and it is safe.

In handle_read () the protocols and transport are both readable.

There is no doubt that a readability condition has been agreed concurrently, evaluated at the same time, from the different state of buffers and the channel’s collector stack. And it is certain that there is data to be read from the socket. The dispatcher is ready to read, the socket is ready to be read.

Idem for handle_write () or any other event handlers dispatched by

handle_read_event ()
handle_write_event ()

There is no uncertainty about the readability or writability.

When a write event is handled, the channel socket *is* writable and the channel protocol is ready to produce output. When the current producer is stalled, if the output_fifo is empty, the channel will not be writable, excluded from the list of sockets polled.

That *when* is an implicit but safe assumption to make, at all times.

Without a single line of code.

So in Allegra there is no need to call pauseProducing () or startReading () after having tested the I/O state of the FileDescriptor … at all steps in both transport and protocols.

Just push producers, let them stall, set collectors, let them collect. And if your protocol does stall, let him just resume buffer collection, nothing more.

If you use async_net, the same assumption holds, but you are expected to make do without stallable producers, just iterables of 8-bit byte strings. This is an alternative for newer, faster, multiplexed and chunked protocols.

In any case, the I/O state is allways tested only once, for each run of the loop. Exactly before the sockets are polled for I/O events, not in between.

And probably with a smaller effect on performance under load than that mambo-jumbo of readability/writablity tests that litter Twisted.

Regards,

]]>
by: Allen Short http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-641 Sun, 21 May 2006 05:55:52 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-641 >If you want to provide application developers with a network component >object model that can plug in the existing *synchronous* API This may be one of your fundamental misunderstandings: We don't. Ever. This is not what Twisted is for. Interfacing with legacy synchronous libraries is one thing, and Twisted has a pretty good record of doing that. Enabling people to write applications that makes bad assumptions about concurrency is another, and there's no support, present or future, for doing that. >If you want to provide application developers with a network component
>object model that can plug in the existing *synchronous* API

This may be one of your fundamental misunderstandings:

We don’t. Ever.

This is not what Twisted is for. Interfacing with legacy synchronous libraries is one thing, and Twisted has a pretty good record of doing that. Enabling people to write applications that makes bad assumptions about concurrency is another, and there’s no support, present or future, for doing that.

]]>
by: Laurent Szyster http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-613 Sat, 20 May 2006 16:00:48 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-613 To Steve: >What’s your excuse for continuing to pollute Planet Python with your diatribes? Peer review. I'm reviewing Twisted. And that comes with harsh criticisms, because it's bad in many ways, nobody's perfect. And some more perfectible than others. There are ugly bugs in probably every software that has not been peer reviewed (unless you are as talented as DJ Bernstein of course). Even our Python BDFL made big mistakes. Don't try to defend the project like if it was a sacred cow. There is dissent and it is rational, argumented and factual. I did my first part of the job, reviewing Twisted sources. If you don't want to review Allegra sources, can you defend the one I critic? To Glyph: Python instanciation is reputed to weight 50 times more than the C/C++ equivalent. No wonder the figures are so close (but I would love to see your test code). But 70.000 Finalization per second includes the time it took to instanciate the objects (9.846692 seconds for a million instance) *and* finalize (4.090665). Finalization alone is possibly faster than 250.000 per second on a 1.7Ghz processor, provided that you attribute it to an existing instance, something that would have been instanciated anyway, with or without continuation. And that's the case in Allegra. Because the main difference between defered and finalization is that new instances of Defered are created all over Twisted. In Allegra, Finalizations may be attributed to instances that should have been instanciated anyway, like requets, channels, thread loops, synchronized components, etc ... You can instanciate Finalizations, Branch or Join instance to program complex asynchronous continuations between those instances. But you won't have to in many places. And if you do and that it becomes a burden, it is possible to specialize them for your application purposes. Since each can be a lot more complex than a boolean branch, you will instanciate less of them, making applications of finalization faster. Anything on the four other twisted bits? I read your comments on the second one, that missing couple and its wide effect in Twisted. What about encapsulable and reusable protocols? What about the "downard" slope toward GUI and funky transport layers. What about the absence of a web peer? What about threads and support for synchronization of instance methods? If you want to provide application developers with a network component object model that can plug in the existing *synchronous* API, it must support the common network interface (the web) and have a no-brainer synchronization interface. With the simplest implementation possible: this is Python, not C, each line may weight on performance a 100 times more. Regards, To Steve:

>What’s your excuse for continuing to pollute Planet Python with your diatribes?

Peer review. I’m reviewing Twisted.

And that comes with harsh criticisms, because it’s bad in many ways, nobody’s perfect. And some more perfectible than others. There are ugly bugs in probably every software that has not been peer reviewed (unless you are as talented as DJ Bernstein of course). Even our Python BDFL made big mistakes.

Don’t try to defend the project like if it was a sacred cow.

There is dissent and it is rational, argumented and factual. I did my first part of the job, reviewing Twisted sources. If you don’t want to review Allegra sources, can you defend the one I critic?

To Glyph:

Python instanciation is reputed to weight 50 times more than the C/C++ equivalent. No wonder the figures are so close (but I would love to see your test code). But 70.000 Finalization per second includes the time it took to instanciate the objects (9.846692 seconds for a million instance) *and* finalize (4.090665).

Finalization alone is possibly faster than 250.000 per second on a 1.7Ghz processor, provided that you attribute it to an existing instance, something that would have been instanciated anyway, with or without continuation. And that’s the case in Allegra.

Because the main difference between defered and finalization is that new instances of Defered are created all over Twisted. In Allegra, Finalizations may be attributed to instances that should have been instanciated anyway, like requets, channels, thread loops, synchronized components, etc …

You can instanciate Finalizations, Branch or Join instance to program complex asynchronous continuations between those instances. But you won’t have to in many places.

And if you do and that it becomes a burden, it is possible to specialize them for your application purposes. Since each can be a lot more complex than a boolean branch, you will instanciate less of them, making applications of finalization faster.

Anything on the four other twisted bits? I read your comments on the second one, that missing couple and its wide effect in Twisted.

What about encapsulable and reusable protocols? What about the “downard” slope toward GUI and funky transport layers. What about the absence of a web peer? What about threads and support for synchronization of instance methods?

If you want to provide application developers with a network component object model that can plug in the existing *synchronous* API, it must support the common network interface (the web) and have a no-brainer synchronization interface. With the simplest implementation possible: this is Python, not C, each line may weight on performance a 100 times more.

Regards,

]]>
by: mark http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-601 Sat, 20 May 2006 11:50:37 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-601 These posts do provide one useful service though. I know you don't understand enough about the issues (or are totally focused on the wrong things) for me to bother trying allegra and you have gotten an awful lot of useful information from the Twisted guys. These posts do provide one useful service though. I know you don’t understand enough about the issues (or are totally focused on the wrong things) for me to bother trying allegra and you have gotten an awful lot of useful information from the Twisted guys.

]]>
by: Glyph Lefkowitz http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-590 Sat, 20 May 2006 06:32:50 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-590 Laurent, You mentioned the number 70,000 in one benchmark, so I will do you one better: I can instantiate, run, and finalize well over 100,000 Deferreds per second on this 1.5MhZ laptop, even while downstepped on battery power to 600 MhZ. This is not using any optimizations, such as James Knight's C version of Deferred, which I have heard rumored is 3x as fast. While Deferreds can be a bottleneck in extremely performance-intensive applications, they are generally more-efficient than ad-hoc abstractions that try to do the same thing. Laurent,

You mentioned the number 70,000 in one benchmark, so I will do you one better: I can instantiate, run, and finalize well over 100,000 Deferreds per second on this 1.5MhZ laptop, even while downstepped on battery power to 600 MhZ.

This is not using any optimizations, such as James Knight’s C version of Deferred, which I have heard rumored is 3x as fast.

While Deferreds can be a bottleneck in extremely performance-intensive applications, they are generally more-efficient than ad-hoc abstractions that try to do the same thing.

]]>
by: Steve http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-589 Sat, 20 May 2006 06:09:47 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-589 I am afraid I agree with the other commenters here. If you have to knock twisted to justify your own code then you should stop trying to justify your own code. If it doesn't stand alone then it has no right to exist. At least twisted has justified its existence by proving its utility. What's your excuse for continuing to pollute Planet Python with your diatribes? I am afraid I agree with the other commenters here. If you have to knock twisted to justify your own code then you should stop trying to justify your own code.

If it doesn’t stand alone then it has no right to exist. At least twisted has justified its existence by proving its utility. What’s your excuse for continuing to pollute Planet Python with your diatribes?

]]>
by: Nicola Larosa http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-588 Sat, 20 May 2006 05:44:58 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-588 This misguided attempt to piggyback on Twisted's popularity is making an ass of yourself. It's just sad. This misguided attempt to piggyback on Twisted’s popularity is making an ass of yourself. It’s just sad.

]]>
by: Andrew http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-587 Sat, 20 May 2006 04:20:20 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-587 "The purpose of defered success and failure is to implement a common pattern: the two way branch." No, it's as Allen already said: precisely the same reason Python has “return” and “raise”. Plenty has been written about why Deferreds are designed the way they are, you don't need to make up reasons. It's clear that you misunderstand much of the design of Twisted, and have no intent of trying to understand it except to criticise. I've seen no sign that you've actually attempted to write anything with Twisted, or examined code of actual applications happily using Twisted. If you want to really impress people about Allegra vs. Twisted, if that really matters so much to you, rather than abstract arguments about how the code is factored, *take a real application written with Twisted and rewrite it to use Allegra*, and blog about how much better you think the Allegra version is. Give a concrete, real-world example for once. In several entries now you persist in claiming the lack of a great HTTP 1.1 implementation built on Twisted means Twisted is flawed, rather than the real explanation that no-one cares enough to make it better. No amount of rebuttal from the people involved influences you on this point. And I have to wonder: if you're so happy with Allegra, why bother blogging about Twisted at all? “The purpose of defered success and failure is to implement a common pattern: the two way branch.”

No, it’s as Allen already said: precisely the same reason Python has “return” and “raise”. Plenty has been written about why Deferreds are designed the way they are, you don’t need to make up reasons.

It’s clear that you misunderstand much of the design of Twisted, and have no intent of trying to understand it except to criticise.

I’ve seen no sign that you’ve actually attempted to write anything with Twisted, or examined code of actual applications happily using Twisted. If you want to really impress people about Allegra vs. Twisted, if that really matters so much to you, rather than abstract arguments about how the code is factored, *take a real application written with Twisted and rewrite it to use Allegra*, and blog about how much better you think the Allegra version is. Give a concrete, real-world example for once.

In several entries now you persist in claiming the lack of a great HTTP 1.1 implementation built on Twisted means Twisted is flawed, rather than the real explanation that no-one cares enough to make it better. No amount of rebuttal from the people involved influences you on this point.

And I have to wonder: if you’re so happy with Allegra, why bother blogging about Twisted at all?

]]>
by: Laurent Szyster http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-573 Sat, 20 May 2006 02:45:16 +0000 http://laurentszyster.be/blog/labeling-the-twisted-bits/#comment-573 >No, you miss my point — *you* are the one making these claims. You are responsible for “citing code and stuff”. I did. Have you followed the links? >"Defered are slow to run and complicated to apply.” What evidence is there for this? For each Defered: an object instanciation, plus a few attributes, plus a list. And then the callbacks, of course. And their loops. And there are defered all over, even in the stream protocols, go figure. For each finalization attributed: a deque.append, plus a single callback, in a single loop for finalized. The CPython VM does the rest: "fire" an event and call __del__ () method. And there are fewer finalizated instances used, only at the usefull articulations where an instance was allready required: request, channels, select_trigger, synchronized components, etc. I actually did benchmark finalizations costing around 70.000 per seconds on a 1.7Ghz PC, instanciating a million of them, chained in a thousand continuations. http://laurentszyster.be/blog/to-the-ravening-hordes/ If you try this with defered, I'm curious to run your test code. >Precisely the same reason Python has “return” and “raise”. First, it's a bad comparison: "success" is the continuation bound to an internal success-state to the defered, "return" is a value followed by a continuation set externaly from the function. And if you need exceptions is it not simpler to just raise one. You can do that in a finalization, actually exiting the continuation it may be part of. The purpose of defered success and failure is to implement a common pattern: the two way branch. Too bad when there are three. Redundant when there is only one option: success and continuation. This is a specific problem of defered as a basic construct for composition of asynchronous continuations. The "failure" option is not needed in many cases where we have a simple pipe, the branch is too short for anything else than "success" or "failure". >>The interface is wrong and the implemention is as bad.” > What evidence is there for this? All of the above. If you want to dispell a myth, do a benchmark yourself. >No, you miss my point — *you* are the one making these claims. You are responsible for “citing code and stuff”.

I did. Have you followed the links?

>”Defered are slow to run and complicated to apply.” What evidence is there for this?

For each Defered: an object instanciation, plus a few attributes, plus a list. And then the callbacks, of course. And their loops. And there are defered all over, even in the stream protocols, go figure.

For each finalization attributed: a deque.append, plus a single callback, in a single loop for finalized. The CPython VM does the rest: “fire” an event and call __del__ () method.

And there are fewer finalizated instances used, only at the usefull articulations where an instance was allready required: request, channels, select_trigger, synchronized components, etc.

I actually did benchmark finalizations costing around 70.000 per seconds on a 1.7Ghz PC, instanciating a million of them, chained in a thousand continuations.

http://laurentszyster.be/blog/to-the-ravening-hordes/

If you try this with defered, I’m curious to run your test code.

>Precisely the same reason Python has “return” and “raise”.

First, it’s a bad comparison: “success” is the continuation bound to an internal success-state to the defered, “return” is a value followed by a continuation set externaly from the function.

And if you need exceptions is it not simpler to just raise one. You can do that in a finalization, actually exiting the continuation it may be part of.

The purpose of defered success and failure is to implement a common pattern: the two way branch. Too bad when there are three. Redundant when there is only one option: success and continuation.

This is a specific problem of defered as a basic construct for composition of asynchronous continuations. The “failure” option is not needed in many cases where we have a simple pipe, the branch is too short for anything else than “success” or “failure”.

>>The interface is wrong and the implemention is as bad.”
> What evidence is there for this?

All of the above.

If you want to dispell a myth, do a benchmark yourself.

]]>