Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 1372 lines (974 sloc) 46.804 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
$Id$

===============================================================================
===============================================================================
                             Introduction
===============================================================================
===============================================================================

------------
What This Is
------------

This file is part roadmap and part wishlist. There's a third part
with stuff that's done, but you can ignore it unless you're morbidly
curious about the project's development history.

The roadmap section is relatively small and lists confirmed changes.
Most of these changes will break existing code, which is why they're
listed here. The changes which don't break programs usually don't
need to be documented this far ahead of time. :)

The larger wishlist section is composed of changes being considered
but which may never come to pass.

Everything is open to discussion, even the confirmed changes. If you
spot something you'd like to comment on, please feel free to mail me
directly. The POE mailing list might be a better place to discuss
changes since several people can discuss what you're commenting on.

Hopefully issues can be worked out before changes are implemented.

-------------------------
Typographical Conventions
-------------------------

Sections marked with "(!!!)" may break existing programs.

Various forms of "Xyz" are used throughout to mean "for every". For
example, "POE::Filter::Xyz" means "for every POE::Filter subclass".

Bits marked with question marks (like "????.??.??") are blanks to be
filled in once their values are determined. They are usually version
numbers and release dates. Almost everywhere, though, their context
gives some idea of the time frame involved. For example, an unknown
date 28 days after some release means that there is at least a month
to fix something after the release. If the release version is also
blank, then you're doubly safe, and so on.

===============================================================================
===============================================================================
                 Deprecations & Changes IN PROGRESS
===============================================================================
===============================================================================

These changes have begun or will begin shortly. If they plan to break
existing programs, there will be at least a month (usually two) of
advance warning.

--------------------------
XyzState to XyzEvent (!!!)
--------------------------

In the wheels, rename XyzState to XyzEvent everywhere. Wheels don't
define states, they emit events. Callivg Wheels' parameters XyzState
has been inconsistent and confusing. It's bitten a lot of people.
Call them what they are instead.

Schedule:

1. Release a version with XyzEvent and XyzState working side by side.
   XyzState becomes undocumented in favor of XyzEvent.

   Done: 2001-07-15.

2. Wait at least 28 days after the release before continuing this
   schedule. Step 3 will be implemented on or after 2001-08-12.

3. Release a version that generates warnings when XyzState is used.

4. Wait at least 28 days after the warning release before continuing
   this schedule. Step 5 will be implemented on or after 2001-09-09.

5. Release a version that does not support XyzState at all.

----------------------------------
Deprecate queue_peek_alarms (!!!)
----------------------------------

The new alarm functions let programs track their alarms by ID, so they
no longer need to peek into POE's alarm queue.

Schedule:

1. Release a version with queue_peek_alarms() deprecated and
   undocumented.

   Done: 2001-07-15.

2. Wait at least 28 days after the release before continuing this
   schedule. Step 3 will be implemented on or after 2001-08-12.

3. Release a version with a deprecation warning in
   queue_peek_alarms().

4. Wait at least 28 days after the release before continuing this
   schedule. Step 5 will be implemented on or after 2001-09-09.

5. Release a version with queue_peek_alarms() removed altogether.

---------------------------
Make Filter Changing Usable
---------------------------

This change adds new features without breaking existing ones. This
change is a prerequisite for input flow control in Wheel::ReadWrite.

2001-07-27 - Refactoring Checklist

1. get_one_start() takes an arrayref of chunks. It does not return
   anything in particular.

   done. documented.

2. get_one() returns an arrayref of 0 or 1 chunks. It does not take
   anything. Actually, it can return 2+ chunks, but it tries to be
   ungreedy.

   done. documented.

3. get_pending() returns undef if nothing is pending.

   done. documented.

4. get_pending() returns an arrayref if something is pending. Check
   for pending data using length(), defined(), or scalar() depending
   on how the filter stores its pending data. Be sure not to test the
   buffer directly for truth, as it may contain a significant 0 or
   undef.

   done. documented.

5. get_pending() does not damage a filter's buffer.

   done. documented.

6. Wheels? Auuuugh!

   Actually, only ReadWrite deals with filter changing. Whew!

   done. documented.

7. Update Filter::Xyz documentation.

   done.

8. Update Wheel::Xyz documentation.

   (doing)

Wheels:
        + ReadWrite

Finishing Touches:

        Dear gods, some of this code sucks! The duplicated code in
        Filter::Line is particularly horrific, not for its structure
        but for the amount of duplication. The way wheels test
        for the end of get_one() loops leaves much to be desired. But
        my brane is focused on getting through this big suite of
        changes today, so I'm not paying too much attention to doing
        it optimally. As my C guru once said, "Get it working, and
        then make it faster."

        Filter::Reference uses a hashref for its $self. Make that an
        arrayref, damnit!

2001-07-16:

Once this is fixed, ReadWrite can use get_one() to fetch one event at
a time. The resume_input() method can, among other things, continue
the get_one() loop if data is already buffered but more isn't ready to
be read.


===============================================================================
===============================================================================
               Deprecations & Changes BEING CONSIDERED
===============================================================================
===============================================================================

These changes are not confirmed yet. They are still under heavy
consideration, and they may never actually happen. Even if they
include deprecation schedules, they are only tentative. I can't
overly stress that this is the wishlist section of the TODO file, but
I'll certainly try. :)

=======
SIGNALS
=======

Several issues grouped together.

----------------------------------
Fix Signal Event Dispatching (!!!)
----------------------------------

Signal propagation (and the _signal event) are vestigial design from a
time when POE was to be the core for a multi-user object environment.
They provide some extra features that make writing MUDs easier, but
they hamper many general programming tasks that POE is now being used
for.

Signal handling needs a basic redesign to make it more conducive to
generic programming, especially for components. The problem is that
handling a signal in one place does not prevent it from being
delivered elsewhere.

The example that brought this to my attention is an IRC client being
written with POE::Component::IRC. The main program traps SIGINT to
prevent the user from accidentally killing the client. Perhaps it
will ask the user to confirm the kill, to prevent errant keystrokes
from doing damage.

However, because SIGINT is delivered everywhere, POE::Component::IRC
dies regardless whether the main program catches that signal. This is
bad because the back-end IRC connection goes away when the user
interface doesn't necessarily want it to.

While the current signal propagation scheme is useful in some cases,
it's bad for the general case. Every component would need to agree
whether it should or shouldn't catch signals in a particular program.
That's madness.

2001-07-26 - Signals Getting Better?

Perl 5.7.2 or so has "safe" signals. Signals are handled in C, and
the main dispatch loop sets flags or something. The upshot is that a
really nasty hack I'd devised doesn't actually need to be implemented.
Furthermore, the other nasty hack (SIGINT polling) can go away once
everyone upgrades to the most bleeding edge perl release.

Hmm... that may not be immediately useful. Plan A goes on.

2001-07-26 - Tentative Release Schedule

1. Release a version with the new signal event dispatching semantics.

   a. The three-phase signal dispatch and side effects.
   b. $kernel->handle_signal() works.

   For backward compatibility, signal handler return values are
   significant unless $kernel->handle_signal() has been called.

   Documentation changes:

   a. Document the new signal handler dispatch phases.
   b. Deprecate (but leave documented) the significance of signal
      handler return values.
   c. Document $kernel->handle_signal() and say it's recommended.

2. Wait at least 28 days after the release. The next stage of
   breakage will fall on or after [to be determined].

3. Release a version that warns when signal handlers return true
   without calling $kernel->handle_signal().

   There will be a number of false positives on the warning,
   unfortunately, but there's definitelay a work-around, and it lets
   people know for sure that things are changing.

   Docmentation changes:

   a. Undocument the significance of signal handler return values.

4. Wait at least 28 days after the release. The next stage of
   breakage will fall on or after [to be determined].

5. Release a version without warnings and without significant signal
   handler return values.

2001-07-24 - Signal Propagation

In this design, signal dispatching happens in three passes.

In the first pass, a given signal is dispatched to the sessions which
registered handlers for it. The dispatch occurs in the order in which
handlers were registered, so older sessions get first crack at
handling signals.

In the second pass, every other session-- excluding the ones which
have received the signal already-- receive a generic _signal event.
Signal dispatch occurs from the root session (POE::Kernel) down
through children and grandchildren until finally the leaf sessions
(those without children) receive them.

The final pass deals with side effects of signals. If the signal was
fatal and no session handled it, then every session is stopped so that
the process can exit.

2001-07-24 - Signal Handling

Regardless how signals propagate, I do want to remove the significance
of signal handlers' return values. They are so easy to mess up,
especially with _default handlers, and it's trivial to create
processes that won't die without serious intervention.

Flagging signals as handled will require a new Kernel method, perhaps
$kernel->handle_signal(), which sets a flag that the dispatch function
(_dispatch_state) checks after the event handler (state) has returned.

handle_signal() could take a bitmask parameter to tell Kernel what to
do next with a signal. Here are some ideas for signal flags.

  0x00: SIGNAL_UNHANDLED

    A no-op, but it lets programmers explicitly say that a signal
    isn't handled, if they so desire.

  0x01: SIGNAL_HANDLED

    Flag the signal as handled. By default, signals won't be handled
    even if handle_signal() is called while they're being dispatched.

  0x02: SIGNAL_SQUELCH

    Tells Kernel to stop propagating the signal beyond this session.
    I'm not sure if this is desired, though. Perhaps it stops the
    dispatch at the end of the phase. For example, all the sessions
    that request SIGHUP would still receive a SIGHUP event even if the
    first one called SIGNAL_SQUELCH, but then the second dispatch pass
    would be bypassed.

    In the dispatch design #1, the side-effects pass will be executed
    even if a signal is squelched. Squelching a signal just prevents
    other sessions from seeing it.

  0x04: SIGNAL_NONTERMINAL

    Forces a signal to be treated as survivable.

  0x08: SIGNAL_TERMINAL

    Forces a signal to be treated as terminal in the final
    side-effects dispatch pass. This makes otherwise benign (possibly
    fictitious) signals suddenly lethal. Consider SIGBOGUS becoming
    terminal.

    Still, though, if the signal is handled with SIGNAL_HANDLED
    anywhere, it won't actually kill anything even if it's flagged
    SIGNAL_TERMINAL.

  0x10: SIGNAL_UNMASKABLE

    Flag the signal as terminal without any hope of handling it.
    SIGZOMBIE is like that.

2001-08-08 - Ideas continue to gel.

I'll probably go ahead with the three-phase dispatch but leave the
return value alone. This shouldn't break much code, since signal
dispatch and propagation already tends to be broken. Most people who
deal with it seriously work around a whole host of problems.

The signal handler semantics will probably remain the same for now.
That's a big area of interface breakage, and it will cause problems
for people.

No... they both should change together. If they don't, people will
use more signal handlers once the dispatch is fixed. There will be
that much more breakage later when the public handler interface
changes.

----------------------------------
SIGTSTP Does the Wrong Thing (???)
----------------------------------

This change depends upon signal dispatching being fixed.

This one's marked with "(???)" because I'm not really sure it'll break
anything.

Gordon Matzigkeit writes 2001-02-16:

| If you haven't already, would you please add TSTP as a signal that
| should not be messed with in POE::Kernel:
|
| if (POE_USES_EVENT) { # include
| # If Event is available, register a signal watcher with it.
| # Don't register a SIGKILL handler, though, because Event
| # doesn't like that.
| if ($signal ne 'KILL' and $signal ne 'STOP'
| and $signal ne 'TSTP' # <-- HERE
| ) {
| Event->signal( signal => $signal,
| cb => \&_event_signal_handler_generic
| );
| }

I responded:

| I think a more correct implementation might set up TSTP and CONT
| handlers like in _APUE_'s program 10.22. That way, POE can
| gracefully suspend and resume itself while also propagating TSTP and
| CONT signals to sessions so they too can perform pause/resume tasks.

2001-07-26 - Update Schedule

A lot of people have been bitten by this. The TSTP handler might go
something like this:

1. Dispatch TSTP according to the current signal dispatch semantics.

2. If anything "handles" the signal, then don't stop the process.

3. If the signal remains unhandled, then stop the process. The code
   to stop a process hasn't been designed yet, but here's the code
   from program 10.22 so I don't have to keep looking in the book.

   int main (void) {
     int n;
     char buf[BUFSIZE];

     /* only catch SIGTSTP if we're running in a job-control shell */
     if (signal(SIGTSTP, SIG_IGN) == SIG_DFL)
         signal(SIGTSTP, sig_tstp);

     /* ... code to do stuff ... */

     exit(0);
   }

   static void sig_tstp(int signo) { /* signal handler for SIGTSTP */
     sigset_t mask;

     /* ... code to set up us the suspend ... */

     /* unblock SIGTSTP, since it's blocked while we're handling it */
     sigemptyset(&mask);
     sigaddset(&mask, SIGTSTP);
     sigprocmask(SIG_UNBLOCK, &mask, null);

     signal(SIGTSTP, SIG_DFL); /* reset disposition to default */
     kill(getpid(), SIGTSTP); /* and send the signal to ourself */

     /* kill won't return until we receive SIGCONT or something */

     signal(SIGTSTP, sig_tstp); /* reestablish signal handler */

     /* ... code to set up us the resume ... */

     return;
   }

4. The process stops in kill() and doesn't resume until kill()
   returns. When kill() returns, dispatch CONT to everyone to let
   them know they've awakened.

======
Wheels
======

Several issues grouped together.

------------------
Wheels Must Evolve
------------------

First, I'd like to say that wheels won't die entirely, but they may
become stubs (thunks?) into some other kind of I/O abstraction.
Certainly it would be more efficient to use the new abstraction
directly, but at least old code won't die.

POE::IO::Stream is the abstraction's planned name. Suggestions are
welcome, and I'll document them here.

IMPLEMENTATION NOTES:

POE::IO::Stream might be just POE::Stream. It might also be
POE::Component::Stream, because it will be implemented as a component.
That is, Sessions creating streams will not actually own their
handles! This is funky, I admit, but it solves a few problems:

* Can't pass Wheel among sessions, because they set states in their
  owners. Since the states won't be set anymore, it's possible to
  pass streams around.

* Can't have multiple sessions watching for input on a single handle.
  Since only POE::IO::Stream is really watching a given handle, that
  rule isn't broken. However, it can be written to multiplex data to
  every session with interest in a stream.

* Can't subclass sessions. Since wheels rely on sessions to have
  predictable argument offsets, every subclassed session's states
  require the same number and order of arguments. This already has
  been a problem with Session vs. NFA.

* In the rare (but it happens often enough) case where a Session quits
  before it removes its wheels, Kernel emits nasty warnings about
  removing states from a nonexistent session. This won't happen
  anymore.

* POE::IO::Stream would need to monitor the comings and goings of
  client sessions without them explicitly signalling it. Here's a
  case for monitors that Philip Gwyn and others have wanted for a
  while now. I can see the utility of such a thing.

* Probably others. I'll add them as I think of them.

The guts of various wheels would be moved into POE::IO::Stream
somewhere, and the wheels themselves would become a compatibility
interface between sessions and the new I/O system.

POE::IO::Stream will use Kernel's refcount_increment() and
refcount_decrement() methods to pass the handle "keep-alive" to
sessions waiting for data.

PUBLIC INTERFACE NOTES:

Stream constructor for file-like things:

  $stream = POE::IO::Stream->open

... must be called with one of these:

    Handle => FILEHANDLE
    Descriptor => DESCRIPTOR
    File => FILENAME
    Device => DEVICE
    Resource => URI

... may also be called with these:

    Modes => FILE_MODES
    Flags => FILE_FLAGS
    Driver => POE::Driver::Xyz->new()
    Filter => ONE_FILTER
    Filter => ARRAYREF_OF_FILTERS

Stream constructor for socket listeners:

  $stream = POE::IO::Stream->listen

    FromAddress => BIND_ADDRESS
    FromPort => BIND_PORT
    Domain => SOCKET_DOMAIN
    Type => SOCKET_TYPE
    Protocol => SOCKET_PROTOCOL
    Flags => SOCKET_OPTIONS
    QueueSize => LISTEN_QUEUE

... see the notes for Handle in the connect() constructor notes.

    Handle => SOCKET_HANDLE

... see the notes on From and To for the connect() constructor.

Stream constructor for socket connectors:

  $stream = POE::IO::Stream->connect

    FromAddress => BIND_ADDRESS
    FromPort => BIND_PORT
    ToAddress => CONNECT_ADDRESS
    ToPort => CONNECT_PORT
    Domain => SOCKET_DOMAIN
    Type => SOCKET_TYPE
    Protocol => SOCKET_PROTOCOL
    Flags => SOCKET_OPTIONS

... to remain similar with the listen constructor, a Handle parameter
can be added instead of Domain, Type, and Protocol. Further,
FromAddress and FromPort can be omitted (they're optional anyway).

    Handle => SOCKET_HANDLE

... people have requested ways to bind to multiple addresses and
ports. Perhaps instead of FromAddress and FromPort, another parameter
can be added:

    From => 'ADDRESS:PORT'
    From => PACKED_ADDRESS
    From => [ 'ADDRESS:PORT', 'ADDRESS:PORT', ... ]
    From => [ PACKED_ADDRESS, PACKED_ADDRESS, ... ]

... likewise, ToAddress and ToPort could be specified:

    To => 'ADDRESS:PORT'
    To => PACKED_ADDRESS

... would multicast be done as arrayrefs for To?

Stream constructor for connectionless sockets:

  $stream = POE::IO::Stream->peer

    FromAddress => BIND_ADDRESS
    FromPort => BIND_PORT

    (ToAddress? ToPort?)

    Domain => SOCKET_DOMAIN
    Type => SOCKET_TYPE
    Protocol => SOCKET_PROTOCOL
    Flags => SOCKET_OPTIONS

... see the notes on From and To for the connect() constructor.

... see the notes for Handle in the connect() constructor.

Each variation of a stream might be its own class. I'm not sure about
that yet, since it fragments the design and makes finding bits of code
harder than usual. What is the benefit again?

Events that can be emitted. These are parameters for the event_xyz()
and constructor methods:

  OnSuccess
  OnError
  OnInput
  OnInputDone
  OnOutput
  OnOutputDone
  OnExpedite
  OnExpediteDone
  OnDonner
  (not really)
  OnInputError
  OnOutputError
  OnExpediteError
  OnOutputFull
  OnOutputEmpty
  OnExpediteFull
  OnExpediteEmpty

These are common methods for most/all of the differently constructed
streams:

  filter_push
  filter_pop
  filter_swap

  event_set
  event_clear

  close RWX_FLAGS
  pause RWX_FLAGS
  resume RWX_FLAGS

... maybe more.

-----------------------------------------
Wheel::ReadWrite Needs Input Flow Control
-----------------------------------------

This change depends on fixed filter changing.

2001-07-16

Rewrote this section. After lots of thought, note-taking, some
experimentation, and copious discussion with Torvald Riegel on the
subject, I've decided on two kinds of input throttling. Neither kind
uses input buffers, which probably will upset Torvald. He strongly
believes in input buffering within ReadWrite, and I strongly disagree
with him. We've been disagreeing on the subject for months.

The first form of flow control uses Torvald's proposed pause_input()
and resume_input() methods for ReadWrite. In prototypes, they have
successfully been driven by high- and low-water events from other
wheels. That is, when the "write" wheel's output buffer fills up, it
pauses input on the "read" wheel. The prototype is symmetric; each
wheel throttles the other. I think it can be expanded into a useful
stand-alone component for piping data between two handles. It would
simplify the proxy sample.

The second form of flow control is flawed, and I need to work on it
some more before including it here.

2001-07-26 - Related Issues

This won't ever get off the ground until POE::Filter::Xyz are
de-optimized. Bleah! But it's the right thing to do after all these
years.

2001-07-26 - Update Schedule

1. Release a version with POE::Wheel methods pause_input() and
   resume_input() from Torvald's patch.

   Document the new methods, and add tests for them.

   Do the other thing, which isn't fully designed yet.

2. Release it!

2001-08-08 - Status

Filter::Xyz are deoptimized, I think. I need to expand test 19 to try
changing filters rapidly before I close that. Test 19 hurts my brain.

--------------------------------
Make Things Inheritance-Friendly
--------------------------------

There was a time in POE's development where just using @ISA would make
method calls three times slower. Whatever perl was doing got fixed,
and now it's safe to use inheritance again.

    b01_solo: 13 wallclock secs ( ... ) @ 924187.73/s (n=10000000)
  b02_parent: 12 wallclock secs ( ... ) @ 901408.45/s (n=10000000)
   b03_child: 12 wallclock secs ( ... ) @ 919540.23/s (n=10000000)

Session should be made inheritable, if it's not already. The base
Wheel, Filter, and Driver classes maybe. Component could provide some
useful common things; perhaps Philip Gwyn can add interoperability
stuff there and make components do the right things.

Kernel? Should it be inheritable?

2001-07-25 - Status

Removed const and enum from Session and NFA, turning them into plain
constant subs instead. This makes the constants inheritable.
Something must be done about the macros, though. I may have to back
them out into method calls, which WILL be slower than inlined code.

2001-08-08 - Status

Requires wheels not to be so closely tied to sessions. Especially
requires them not to insert states into sessions, since different
kinds of sessions may have different parameter orders or counts. See
POE::IO::Stream somewhere else in this document.

========
Etcetera
========

---------------------------
Simplify Session Definition
---------------------------

This change requries that sessions be made inheritance friendly.

Add new base classes: POE::Session::Inline, POE::Session::Object, and
POE::Session::Package. Each somehow scours their subclasses'
namespaces for methods or functions that begin with "poe_". The base
classes provide a poe_spawn() method that uses the "poe_" symbols to
build and instantiate inline, object, and package sessions
automatically.

This would vastly simplify session definitions, for many simple cases.

package ThingySession;

@ThingySession::ISA = qw( POE::Session::Object );

sub poe__start { # two underscores
  ...
}

sub poe__stop { # two underscores
  ...
}

sub poe_event {
  ...
}

sub private_method {
}

1;
__END__

Programs would call ThingySession->spawn() to create a new object
session with the "poe_" methods as event handlers.

I think Artur Bergman mentioned this to me once, but I was too busy to
think about it. It's a rocking idea, though.

-----------------------
POE One-Liners are HARD
-----------------------

It's a shame that you can't write many one-liners in POE. What can be
done about this?

My first inclination is to develop something SO high level that it
does what you mean. My second inclination is to hit myself in the
head until I stop thinking about it. :)

----------------------------------------------------
The POE Community Wants a Bigger Hand in Development
----------------------------------------------------

The YAPC 2001 POE BOF agreed that its members want a bigger part in
the project's development. This is great! It should reduce my
workload and generally expand POE knowledge across a larger group of
people. If I get hit by a passing blimp, life goes on without me.

For such a group to remain organized, however, I feel the need to
codify the goals and heuristics that guide my own development.
Certainly these would just be guidelines. Evolution happens, and they
may change over time as the project continues to grow up, but it's a
good idea to know going into it what's expected to come out of it.

So, what am I trying to do here? What are the decision priorities
when making trade-offs? Where do I want to go today?

2001-07-26 - Still Not Done

I'm finding this a lot easier to say than to do.

---------------------------------------
Give Exported Constants Some Prefix(es)
---------------------------------------

This change depends on sessions becoming inheritance friendly. I'd
like to put the prefix thing into a base class so everyone can enjoy
it.

<Micksa> eep, poe uses yet another calling convention
<Micksa> like:
<Micksa> my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
<Fletch> that's the normal convention, it just doesn't hardcode what
         order particular arguments will be passed
<Micksa> it's, like, the 4th way I've seen so far for passing named
         parameters.
<Fletch> it's so that if calling order ever changes programs that use
         the symbolic constants don't break
<Fletch> it's really no different than say
         `my($kernel,$heap)=@_[0,3]', just that the 0 and 3 come from
         constant subs rather than magic numbers
<Micksa> problem is, the symbolic constants are rather likely to
         clash.
<Fletch> maybe there could be an option to prefix them, like
         poe_KERNEL or P_KERNEL?
<Micksa> *shrug*

That sounds like a good idea.

2001-07-25 - Development

use POE::Session qw( ConstPrefix => 'POE_SESSION_' );

---------------------------------
ASSERT_XYZ and TRACE_XYZ Are Ugly
---------------------------------

It would also be fun to tweak TRACE_ and ASSERT_ through POE::Kernel's
and POE::Session's import() methods.

use POE::Session qw( Traces => [ DEFAULT => 1, GARBAGE => 0 ] ) ... or
something.

2001-07-26 - More ideas

use POE::Tweak qw( Trace => qw( +default -garbage ),
                   Assert => qw( +default -reference ),
                 );

Tweaks would be global.

2001-08-08 - Development

The previous idea is still too verbose. Here's something easier that
Artur came up with. Artur would like to see a POE::strict directive
that turns on everything. It's certainly more convenient than the
other goop. So:

  use POE::strict qw( events states parameters returns );
  use POE::assert qw( default -references );
  use POE::trace qw( garbage references );

These would still need to be before the first instance of C<use POE;>
because they dis/enable things at compile time.

Known interested people: Artur, Rocco :)

-------
Threads
-------

Artur is working tirelessly on iThreads (now C<use threads;> in 5.8.0
or something). He's even got a patch to POE::Kernel with adds them.
I need a day's worth of tuits to try this out.

Threads would really enhance IKC.

Known interested people: Artur, YAPC::EU

--------
Security
--------

POE needs a thorough code review. It needs to stay still long enough
to be examined. :)

Known interested people: Artur, YAPC::EU

--------------------------
Inter-Kernel Communication
--------------------------

Artur says there's a need for an official IKC. I'd rather let
Philip's become it than try to write my own. I guess maybe what
Artur's asking for is tighter integration between POE and IKC.

To do: Find out what Artur means. :)

Known interested people: Artur, YAPC::EU

-------------------
Automatic Postbacks
-------------------

Torvald Riegel writes:

  What do you think about some sort of automatic postbacks? A third
  type of generating an event, which would be posted to the target
  session. The associated state's return value would be returned to a
  postback that is specified when sending the first event. So one
  would use something like $kernel->postandreply($target, $event,
  $self->postback(...), @args)...

  Advantages would be that the target session would not need to care
  about handling postbacks and returning values through them. One
  more function would have to be maintained and postacks would need to
  be kept somewhere at the event's structures. Garbage collection
  shouldn't be a problem since the postback would be a normal
  parameter otherwise.

  Really good would be if this return-postback could be set as another
  state's return-postback. So if user() would postandreply server()
  but server() would have to call worker(), the postback could be
  handed over to worker() and it would reply through the postback.
  This would only be a variation of postandreply, I think.

  I know everything could be done using postbacks given as state
  arguments, but the above would make returning values simple and
  easier to read at the server() side.

Others have requested it too.

----------------------------------------
Even Simpler POE::Component::Server::TCP
----------------------------------------

Artur would like PoCo::Server::TCP to be simpler. In fact, he'd like
it to be so simple that it wraps accepted sessions as well, possibly
not spawning new sessions at all.

The idea would be to provide Reader, Writer, and/or Error handlers
instead of Acceptor. The server component would do its accept thing
and create a generic session (possibly not) that does generic reading
and writing. The handlers would customize things from there.

Artur has some specific ideas how this should work.

2001-08-08 - Status

I haven't seen Artur's specifications, but embedding the ReadWrite
into the server component would let Fletch write Server::SSL as a
drop-in replacement for Server::TCP. That's fun.

-------------------------------------------
Change Internal Helpers To Static Functions
-------------------------------------------

This change may never happen if it hinders the ability to inherit
stuff.

Despite recent optimizations in perl 5, object methods are still a wee
bit slower than function calls. Furthermore, those changes aren't in
older versions of perl where POE still runs fine.

Because of Kernel restructuring in 0.05_02 (1999.01.12) prohibiting
multiple Kernel instances, we can finally make POE::Kernel's private
methods static functions.

What do we get? Better performance (by a factor of 3 or so) in older
versions of perl. Less argument passing internally (no $self; the
lexical $poe_kernel instead). Greater encapsulation, but who cares
about that?

This is a relatively easy change, and it would make a good starter
project for someone who wants to get familiar with Kernel.pm and
Kernel/*.pm.

2001-07-29 - Chances Decreasing

The more I think about this one, the less I like doing it. At some
point, things should be subclassable.

----------------------
Batch Remove Resources
----------------------

Peter J. Braam would like a way to flush all pending events for a
session. This would be FIFO events, since there would already be a
method for alarms.

Kirill would like a way to batch-remove all selects when it's time for
a session to shut down.

+ alarm_remove_all() is done

To do:

* Add select_remove_all()

  Wheels confound the ability to remove all selects.

* Add event_remove_all()

Notes:

Other resources which keep a session alive: extra reference counts,
and aliases. Should there be batch remove functions for these as
well?

I'm starting to worry about the side effects of stopping sessions
willy-nilly. Is there a good example of stopping a session while it's
busy processing events? "Good" means the session won't corrupt
anything by not handling whatever is in its queue.

What of everything_remove_all() ?

-------------------------------------------------------
POE::Kernel's yield() is Nearly Universally Hated (!!!)
-------------------------------------------------------

Especially by people who know threads. It implies blocking in one
session and resumption in some other, and it freaks people out when it
returns immediately.

These names have been suggested instead:

  post_self (2 votes)
  post_me (1 vote)
  post_myself (1 vote)
  postal :) (0 votes)
  enqueue (1 vote)
  postpend (1 vote)
  continuation (1 vote)
  continue (0 votes)
  $session->post (2 votes)

This is a pretty basic function, and it's one a lot of people are
probably using. This deprecation should have a longer than usual
schedule, to avoid unnecessary breakage.

The $session->post() idea is doable, but not until Session and NFA can
be subclassed. There's another section in this TODO file about
subclassable sessions.

-------------------------------------------------
POE::Kernel's call() Pretty Much Sucks, Too (!!!)
-------------------------------------------------

The call() method is incongruous, and that's putting it nicely. It
should be deprecated for inter-session calls, and it should probably
become $session->call to match $session->post, or something.

General ideas:

Eliminate the ability to call() outside the current session.

Possibly move the call() method to POE::Session. $session->call() ?

-----------------------
ARG0..ARG9 May Go (!!!)
-----------------------

HEAP, KERNEL, SESSION, and the other event handler parameter constants
were introduced to eliminate a dependence on their positions in @_.
However, the ARG0..ARG9 parameters aren't descriptive and still
contain position dependence. This robs event parameters of many of
the benefits of using symbolic constants in the first place.

This is the current plan to deprecate them:

* Introduce new constants for the different built-in events. Leave
  ARG0..ARG9 for user parameters.

* Document the new constants instead of ARG0..ARG9.

* Document that parameters may move around in the future, so their
  positions in ARG0..ARG9 will not be guaranteed.

* Release version ?.??.

* Wait at least 28 days after releasing the documentation change
  (until ????.??.??) before continuing this deprecation schedule, to
  give people time to react to the initial round of changes.

* Generate warnings when ARG0..ARG9 are used for built-in events.
  This will require some logic within those subs, removing their
  constant nature and slowing things down in general.

* Release version ?.??, and announce that the ARG0..ARG9 built-in
  parameter deprecation is proceding apace.

* Wait at least 28 days after releasing the warnings (until
  ????.??.??) before continuing this deprecation schedule, to give
  people time to react to the warnings and adapt their code to the new
  symbolic constants.

* Remove the warnings from ARG0..ARG9, making them constants again and
  speeding things up once more.

* Release version ?.??, and announce that the ARG0..ARG9 built-in
  parameter deprecation has completed.

-------------------
Finish POE::Message
-------------------

POE::Message would be a high-level inter-session message object,
trading away some speed for a lot of useful features:

  It can encapsulate named parameters instead of the vaguely icky
  ARG0..ARG9.

  It can encapsulate several postbacks, including refcounts which keep
  the sender alive.

  It can encapsulate inter-Kernel routing, messaging, and directory
  services.

  It can encapsulate automatic postbacks and exceptions.

I have a prototype which must be developed further before entering the
repository.

---------------------------
Automatic Parameter Exports
---------------------------

Turn @_[KERNEL, HEAP, etc.] into regular variables, somehow. A lot of
people would like this, and the original object layer had code to do
this. Of course it cheated: all code was kept in a database and had
to be eval'd into existence, so it could do what it liked to your
programs. But still, that was a good idea, it still is, and someone
should do something about it.

----------------------------
Spin Off Useful Technologies
----------------------------

POE only really needs a few modules. The rest are options which may
not always be needed, or they're stand-alone modules that someone else
may find useful. For example, POE::Filter::*; POE::Preprocessor; and
POE::Pipe::* are useful by themselves. Wheels are pretty useful, but
they're not always necessary. It may be both useful and convenient to
split POE into smaller distributions and present one or more Bundles
to selectively load just the parts that are needed.

This is the current plan to spin off useful modules from POE:

* Develop a real plan for this. Most of this is tentative.

* Organize subsets of POE into useful bundles, and document them.
  Make Bundle::POE the default.

* Split out wheels?

* Split out the Preprocessor? Should it remain a POE::* module?

* Split out filters? They're useful by themselves; should they remain
  POE::* modules?

* The samples are huge and obscure. Split them into a separate
  distribution which doesn't install itself.

* Most of the documentation is theory and usage, and it doesn't really
  fit in manpages for modules themselves. Split it into separate POD
  files, and maybe split them into Bundle::POE::Docs.

-----------------------------------------
Make Driver::SysRW the Default for Wheels
-----------------------------------------

This is a quick, inexpensive change. Driver::SysRW is the only driver
to be developed/used over the course of like three years. Make it a
default so people can stop typing it.

This should be an easy fix, but it involves tweaking several wheels.
It might be a nice introduction to wheels for someone who wants to
know more about them.

----------------------------------------
Make Filter::Line the Default for Wheels
----------------------------------------

This is an inexpensive change, but it has dubious value. Think about
it some more first.

This should be an easy fix, but it involves tweaking several wheels.
It might be a nice introduction to wheels for someone who wants to
know more about them.

----------------------------------------------------
Split Dual-Mode Functions into xyz_set and xyz_clear
----------------------------------------------------

This would make the functions' purposes more clear and eliminate some
branches that are currently tested all the time. The existing
dual-mode functions could remain as thunks for the single-purpose
ones.

The "June 2001" alarms functions already do this. What about
select_xyz and the others?

------------------------------------------------------
Evaluate Torvald Riegel's Synchronous NFA Design (???)
------------------------------------------------------

Torvald wants POE::NFA to run entirely synchronously like a proper
nondeterministic finite state machine ought to. I'm against that
because I haven't seen a proper need for it and it puts what I see as
an artificial limit on the class.

To do:

* Distill Torvald's e-mail on the subject and include a summary here.

* Determine whether his design can be implemented in a way that
  doesn't limit NFA to a strictly correct NFA design. Asynchronous
  NFA events are useful and should also be supported.

--------------
POE::Semaphore
--------------

This is an extra feature.

POE::Semaphore encapsulates a semaphore-like thing. Instead of
blocking and releasing when the semaphore reaches zero, though, it
fires an event.

Tied scalar.

raise() and lower() methods.

Constructor takes details of the event to fire. Possibly acts as a
postback or creates one internally.

---------------------
Session Relationships
---------------------

POE::Relationship::Channel or something - A subscribe/broadcast model,
useful for inter-session communication channels and monitors. Philip
Gwyn has wanted monitors for a long time. CanyonMan wants something
similar for inter-session coordination.

POE::Relationship::Matrix - An XY or XYZ grid of sessions with
neighbors. Methods to add and remove sessions. Methods to broadcast
events to neighbors based on radius or some other distance.

POE::Relationship::Network - A directed graph of sessions, suitable
for writing neural or other networks. Convenience methods for
broadcasting events to connected sessions.

------------------------------
Delay Garbage Collection (???)
------------------------------

POE's garbage collection can be slow. It would be very cool to
schedule this in the "dead" time between events. Especially in
instances where the next event is a timer and we have a few seconds of
nothing to do.

A lot of things rely on timely garbage collection, though. _parent
and _child events. Referential integrity. Things would be a mess
between _stop and the delayed garbage collection.

Delaying alarm GC might be doable. We can flag alarms as "dead" in
the ID->time hash and discard them as they come to the front of the
queue. In idle times when there are no FIFO events and the next alarm
is more than 1/10 second away, we can sweep the alarm queue and pull
out the dead ones.

It will take a fair amount of planning to pull this off correctly.
I'm just documenting it for now so I don't forget.

-----------------------------------
Clean up ASSERT_* and TRACE_* Flags
-----------------------------------

Especially ASSERT_USAGE, ASSERT_RETURNS and TRACE_RETURNS which are
getting silly. Make this stuff macros, at the very least.

-------------------------------------
Batch or Standalone POE::Preprocessor
-------------------------------------

ActiveState's perlapp (PDK) does not recognize source filters and so
cannot "compile" POE programs into stand-alone applications. Source
filters may not be available elsewhere, so it would be useful to let
developers statically preprocess applications into stand-alone files.

This sort of preprocessing would kill the startup delay filters have
introduced.

Known interested people: Ilya Melamed (he requested it)

----------------------
Named State Parameters
----------------------

Doable with backwards compatibility. Add a create-time option:

  options => { named_parameters => 1 }

Which changes the dispatch semantics to hashref instead of arrayref.

Known interested people: Sungo, Coral, Artur, Lenzo

---------------------------
Pluggable Queue Disciplines
---------------------------

Add the ability to change the way events are dispatched. Priority
queues instead of FIFO, or something. Possibly a POE2 kind of thing.

Known interested people: Lenzo


===============================================================================
===============================================================================
                          Stuff That's DONE
===============================================================================
===============================================================================

-----------------------
Improve Alarm Interface
-----------------------

This change adds new features without breaking the way old ones work.

Schedule:

1. Release a version with the new functions in place.

   Done: 2001-07-15.

2. Optimize the new functions.

   Done: 2001-07-26

   I decided against using macros because bits of the alarm adjustment
   code were different from the alarm setting code. The reason?
   Adjusting an alarm doesn't have to look at the whole queue. It
   only needs to look towards the beginning or end of the queue,
   depending on the direction of the adjustment.

Notes:

+ alarm_set(), alarm_adjust(), and alarm_remove() are done
+ delay_set() is done
+ alarm_remove_all() is done

- decided against alarm_remove_by_event(); use alarm() instead
- decided against alarm_remove_by time(); it's not very useful


===============================================================================
===============================================================================
                                 EOT
===============================================================================
===============================================================================
Something went wrong with that request. Please try again.