/usr/share/doc/libcaf-dev/manual.html is in libcaf-dev 0.13.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 | <!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="hevea 2.23">
<style type="text/css">
.li-itemize{margin:1ex 0ex;}
.li-enumerate{margin:1ex 0ex;}
.dd-description{margin:0ex 0ex 1ex 4ex;}
.dt-description{margin:0ex;}
.toc{list-style:none;}
.footnotetext{margin:0ex; padding:0ex;}
div.footnotetext P{margin:0px; text-indent:1em;}
.thefootnotes{text-align:left;margin:0ex;}
.dt-thefootnotes{margin:0em;}
.dd-thefootnotes{margin:0em 0em 0em 2em;}
.footnoterule{margin:1em auto 1em 0px;width:50%;}
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
.title{margin:2ex auto;text-align:center}
.titlemain{margin:1ex 2ex 2ex 1ex;}
.titlerest{margin:0ex 2ex;}
.center{text-align:center;margin-left:auto;margin-right:auto;}
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
td table{margin:auto;}
table{border-collapse:collapse;}
td{padding:0;}
.cellpadding0 tr td{padding:0;}
.cellpadding1 tr td{padding:1px;}
pre{text-align:left;margin-left:0ex;margin-right:auto;}
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
td p{margin:0px;}
.boxed{border:1px solid black}
.textboxed{border:1px solid black}
.vbar{border:none;width:2px;background-color:black;}
.hbar{border:none;height:2px;width:100%;background-color:black;}
.hfill{border:none;height:1px;width:200%;background-color:black;}
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px; border:none;}
.dcenter{margin:0ex auto;}
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
.marginpar{border:solid thin black; width:20%; text-align:left;}
.marginparleft{float:left; margin-left:0ex; margin-right:1ex;}
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
.part{margin:2ex auto;text-align:center}
.lstlisting{font-family:monospace;white-space:pre;margin-right:auto;margin-left:0pt;text-align:left}
body{width:600px;margin:auto;padding-top:20px;text-align: justify;}
</style>
<title>CAF
A C++ framework for actor programming
User Manual
CAF version 0.13.2
</title>
</head>
<body >
<!--HEVEA command line is: /usr/bin/hevea -I .. manual.tex -->
<!--CUT STYLE article--><!--CUT DEF section 1 --><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain"><span style="font-family:monospace"><span style="font-size:xx-large"><span style="font-weight:bold">CAF</span></span></span><br>
<br>
A C++ framework for actor programming<br>
<br>
<br>
<br>
User Manual<br>
CAF version 0.13.2</h1><h3 class="titlerest">Dominik Charousset</h3></td></tr>
</table><!--TOC section id="sec1" Contents-->
<h2 id="sec1" class="section">Contents</h2><!--SEC END --><ul class="toc"><li class="li-toc">
<a href="#sec2">1 Introduction</a>
<ul class="toc"><li class="li-toc">
<a href="#sec3">1.1 Actor Model</a>
</li><li class="li-toc"><a href="#sec4">1.2 Terminology</a>
<ul class="toc"><li class="li-toc">
<a href="#sec5">1.2.1 Actor Address</a>
</li><li class="li-toc"><a href="#sec6">1.2.2 Actor Handle</a>
</li><li class="li-toc"><a href="#sec7">1.2.3 Untyped Actors</a>
</li><li class="li-toc"><a href="#sec8">1.2.4 Typed Actor</a>
</li><li class="li-toc"><a href="#sec9">1.2.5 Spawning</a>
</li><li class="li-toc"><a href="#sec10">1.2.6 Monitoring</a>
</li><li class="li-toc"><a href="#sec11">1.2.7 Links</a>
</li></ul>
</li></ul>
</li><li class="li-toc"><a href="#sec12">2 First Steps</a>
<ul class="toc"><li class="li-toc">
<a href="#sec13">2.1 Features Overview</a>
</li><li class="li-toc"><a href="#sec14">2.2 Supported Compilers</a>
</li><li class="li-toc"><a href="#sec15">2.3 Supported Operating Systems</a>
</li><li class="li-toc"><a href="#sec16">2.4 Hello World Example</a>
</li></ul>
</li><li class="li-toc"><a href="#sec17">3 Pattern Matching</a>
<ul class="toc"><li class="li-toc">
<a href="#sec18">3.1 Basics</a>
</li><li class="li-toc"><a href="#sec19">3.2 Atoms</a>
</li><li class="li-toc"><a href="#sec20">3.3 Advanced Match Cases</a>
</li><li class="li-toc"><a href="#sec21">3.4 Wildcards</a>
</li><li class="li-toc"><a href="#sec22">3.5 Projections</a>
</li><li class="li-toc"><a href="#sec23">3.6 Dynamically Building Messages</a>
</li></ul>
</li><li class="li-toc"><a href="#sec24">4 Actors</a>
<ul class="toc"><li class="li-toc">
<a href="#sec25">4.1 Implicit <span style="font-family:monospace">self</span> Pointer</a>
</li><li class="li-toc"><a href="#sec26">4.2 Interface</a>
</li></ul>
</li><li class="li-toc"><a href="#sec27">5 Sending Messages</a>
<ul class="toc"><li class="li-toc">
<a href="#sec28">5.1 Replying to Messages</a>
</li><li class="li-toc"><a href="#sec29">5.2 Delaying Messages</a>
</li><li class="li-toc"><a href="#sec30">5.3 Forwarding Messages in Untyped Actors</a>
</li></ul>
</li><li class="li-toc"><a href="#sec31">6 Receiving Messages</a>
<ul class="toc"><li class="li-toc">
<a href="#sec32">6.1 Class-based actors</a>
</li><li class="li-toc"><a href="#sec33">6.2 Nesting Receives Using <code>become</code><code>/</code><code>unbecome</code></a>
</li><li class="li-toc"><a href="#sec34">6.3 Timeouts</a>
</li><li class="li-toc"><a href="#sec35">6.4 Skipping Messages</a>
</li></ul>
</li><li class="li-toc"><a href="#sec36">7 Synchronous Communication</a>
<ul class="toc"><li class="li-toc">
<a href="#sec37">7.1 Error Messages</a>
</li><li class="li-toc"><a href="#sec38">7.2 Receive Response Messages</a>
</li><li class="li-toc"><a href="#sec39">7.3 Synchronous Failures and Error Handlers</a>
</li></ul>
</li><li class="li-toc"><a href="#sec40">8 Management & Error Detection</a>
<ul class="toc"><li class="li-toc">
<a href="#sec41">8.1 Links</a>
</li><li class="li-toc"><a href="#sec42">8.2 Monitors</a>
</li><li class="li-toc"><a href="#sec43">8.3 Error Codes</a>
</li><li class="li-toc"><a href="#sec44">8.4 Attach Cleanup Code to an Actor</a>
</li></ul>
</li><li class="li-toc"><a href="#sec45">9 Spawning Actors</a>
</li><li class="li-toc"><a href="#sec46">10 Message Priorities</a>
</li><li class="li-toc"><a href="#sec47">11 Network Transparency</a>
<ul class="toc"><li class="li-toc">
<a href="#sec48">11.1 Publishing of Actors</a>
</li><li class="li-toc"><a href="#sec49">11.2 Connecting to Remote Actors</a>
</li></ul>
</li><li class="li-toc"><a href="#sec50">12 Network IO</a>
<ul class="toc"><li class="li-toc">
<a href="#sec51">12.1 Spawning Brokers</a>
</li><li class="li-toc"><a href="#sec52">12.2 Broker Interface</a>
</li><li class="li-toc"><a href="#sec53">12.3 Broker-related Message Types</a>
</li></ul>
</li><li class="li-toc"><a href="#sec54">13 Group Communication</a>
<ul class="toc"><li class="li-toc">
<a href="#sec55">13.1 Anonymous Groups</a>
</li><li class="li-toc"><a href="#sec56">13.2 Local Groups</a>
</li><li class="li-toc"><a href="#sec57">13.3 Remote Groups</a>
</li><li class="li-toc"><a href="#sec58">13.4 Spawning Actors in Groups</a>
</li></ul>
</li><li class="li-toc"><a href="#sec59">14 Managing Groups of Workers</a>
<ul class="toc"><li class="li-toc">
<a href="#sec60">14.1 Predefined Dispatching Policies</a>
<ul class="toc"><li class="li-toc">
<a href="#sec61">14.1.1 <code>actor_pool</code><code>::</code><code>round_robin</code></a>
</li><li class="li-toc"><a href="#sec62">14.1.2 <code>actor_pool</code><code>::</code><code>broadcast</code></a>
</li><li class="li-toc"><a href="#sec63">14.1.3 <code>actor_pool</code><code>::</code><code>random</code></a>
</li></ul>
</li><li class="li-toc"><a href="#sec64">14.2 Example</a>
</li></ul>
</li><li class="li-toc"><a href="#sec65">15 Platform-Independent Type System</a>
<ul class="toc"><li class="li-toc">
<a href="#sec66">15.1 User-Defined Data Types in Messages</a>
</li></ul>
</li><li class="li-toc"><a href="#sec67">16 Blocking API</a>
<ul class="toc"><li class="li-toc">
<a href="#sec68">16.1 Receiving Messages</a>
</li><li class="li-toc"><a href="#sec69">16.2 Receiving Synchronous Responses</a>
</li><li class="li-toc"><a href="#sec70">16.3 Mixing Actors and Threads with Scoped Actors</a>
</li></ul>
</li><li class="li-toc"><a href="#sec71">17 Strongly Typed Actors</a>
<ul class="toc"><li class="li-toc">
<a href="#sec72">17.1 Spawning Typed Actors</a>
</li><li class="li-toc"><a href="#sec73">17.2 Class-based Typed Actors</a>
</li></ul>
</li><li class="li-toc"><a href="#sec74">18 Messages</a>
<ul class="toc"><li class="li-toc">
<a href="#sec75">18.1 Class <span style="font-family:monospace">message</span></a>
</li><li class="li-toc"><a href="#sec76">18.2 Class <span style="font-family:monospace">message_builder</span></a>
</li><li class="li-toc"><a href="#sec77">18.3 Extracting</a>
</li><li class="li-toc"><a href="#sec78">18.4 Extracting Command Line Options</a>
</li></ul>
</li><li class="li-toc"><a href="#sec79">19 Common Pitfalls</a>
<ul class="toc"><li class="li-toc">
<a href="#sec80">19.1 Defining Patterns</a>
</li><li class="li-toc"><a href="#sec81">19.2 Event-Based API</a>
</li><li class="li-toc"><a href="#sec82">19.3 Synchronous Messages</a>
</li><li class="li-toc"><a href="#sec83">19.4 Sharing</a>
</li><li class="li-toc"><a href="#sec84">19.5 Constructors of Class-based Actors</a>
</li></ul>
</li><li class="li-toc"><a href="#sec85">20 Appendix</a>
<ul class="toc"><li class="li-toc">
<a href="#sec86">20.1 Class <span style="font-family:monospace">option</span></a>
</li><li class="li-toc"><a href="#sec87">20.2 Using <span style="font-family:monospace">aout</span> – A Concurrency-safe Wrapper for <span style="font-family:monospace">cout</span></a>
</li><li class="li-toc"><a href="#sec88">20.3 Migration Guides</a>
<ul class="toc"><li class="li-toc">
<a href="#sec89">20.3.1 0.8 ⇒ 0.9</a>
</li><li class="li-toc"><a href="#sec93">20.3.2 0.9 ⇒ 0.10 (<span style="font-family:monospace">libcppa</span> ⇒ CAF)</a>
</li><li class="li-toc"><a href="#sec94">20.3.3 0.10 ⇒ 0.11</a>
</li><li class="li-toc"><a href="#sec95">20.3.4 0.11 ⇒ 0.12</a>
</li><li class="li-toc"><a href="#sec96">20.3.5 0.12 ⇒ 0.13</a>
</li></ul>
</li></ul>
</li></ul>
<!--TOC section id="sec2" Introduction-->
<h2 id="sec2" class="section">1 Introduction</h2><!--SEC END --><p>Before diving into the API of CAF, we would like to take the opportunity to discuss the concepts behind CAF and to explain the terminology used in this manual.</p>
<!--TOC subsection id="sec3" Actor Model-->
<h3 id="sec3" class="subsection">1.1 Actor Model</h3><!--SEC END --><p>The actor model describes concurrent entities—actors—that do not share state and communicate only via message passing.
By decoupling concurrently running software components via message passing, the actor model avoids race conditions by design.
Actors can create—“spawn”—new actors and monitor each other to build fault-tolerant, hierarchical systems.
Since message passing is network transparent, the actor model applies to both concurrency and distribution.</p><p>When dealing with dozens of cores, mutexes, semaphores and other threading primitives are the wrong level of abstraction.
Implementing applications on top of those primitives has proven challenging and error-prone.
Additionally, mutex-based implementations can cause queueing and unmindful access to (even distinct) data from separate threads in parallel can lead to false sharing: both decreasing performance significantly, up to the point that an application actually runs slower when adding more cores.</p><p>The actor model has gained momentum over the last decade due to its high level of abstraction and its ability to make efficient use of multicore and multiprocessor machines.
However, the actor model has not yet been widely adopted in the native programming domain.
With CAF, we contribute a library for actor programming in C++ as open source software to ease native development of concurrent as well as distributed systems.
In this regard, CAF follows the C++ philosophy “building the highest abstraction possible without sacrificing performance”.</p>
<!--TOC subsection id="sec4" Terminology-->
<h3 id="sec4" class="subsection">1.2 Terminology</h3><!--SEC END --><p>You will find that CAF has not simply adopted exiting implementations based on the actor model such as Erlang or the Akka library.
Instead, CAF aims to provide a modern C++ API allowing for type-safe as well as dynamically typed messaging.
Hence, most aspects of our system are familiar to developers having experience with other actor systems, but there are also slight differences in terminology.
However, neither CAF nor this manual require any foreknowledge.</p>
<!--TOC subsubsection id="sec5" Actor Address-->
<h4 id="sec5" class="subsubsection">1.2.1 Actor Address</h4><!--SEC END --><p>In CAF, each actor has a (network-wide) unique logical address that can be used to identify and monitor it.
However, the address can <em>not</em> be used to send a message to an actor.
This limitation is due to the fact that the address does not contain any type information about the actor.
Hence, it would not be safe to send it any message, because the actor might use a strictly typed messaging interface not accepting the given message.</p>
<!--TOC subsubsection id="sec6" Actor Handle-->
<h4 id="sec6" class="subsubsection">1.2.2 Actor Handle</h4><!--SEC END --><p>An actor handle contains the address of an actor along with its type information.
In order to send an actor a message, one needs to have a handle to it – the address alone is not sufficient.
The distinction between handles and addresses – which is unique to CAF when comparing it to other actor systems – is a consequence of the design decision to support both untyped and typed actors.</p>
<!--TOC subsubsection id="sec7" Untyped Actors-->
<h4 id="sec7" class="subsubsection">1.2.3 Untyped Actors</h4><!--SEC END --><p>An untyped actor does not constrain the type of messages it receives, i.e., a handle to an untyped actor accepts any kind of message.
That does of course not mean that untyped actors must handle all possible types of messages.
Choosing typed vs untyped actors is mostly a matter of taste.
Untyped actors allow developers to build prototypes faster, while typed actors allow the compiler to fetch more errors at compile time.</p>
<!--TOC subsubsection id="sec8" Typed Actor-->
<h4 id="sec8" class="subsubsection">1.2.4 Typed Actor</h4><!--SEC END --><p>A typed actor defines its messaging interface, i.e., both input and output types, in its type.
This allows the compiler to check message types statically.</p>
<!--TOC subsubsection id="sec9" Spawning-->
<h4 id="sec9" class="subsubsection">1.2.5 Spawning</h4><!--SEC END --><p>“Spawning” an actor means to create and run a new actor.</p>
<!--TOC subsubsection id="sec10" Monitoring-->
<h4 id="sec10" class="subsubsection">1.2.6 Monitoring</h4><!--SEC END --><p>
<a id="sec:monitoring"></a></p><p>A monitored actor sends a “down message” to all actors monitoring it as part of its termination.
This allows actors to supervise other actors and to take measures when one of the supervised actors failed, i.e., terminated with a non-normal exit reason.</p>
<!--TOC subsubsection id="sec11" Links-->
<h4 id="sec11" class="subsubsection">1.2.7 Links</h4><!--SEC END --><p>A link is bidirectional connection between two actors.
Each actor sends an “exit message” to all of its links as part of its termination.
Unlike down messages (cf. <a href="#sec%3Amonitoring">1.2.6</a>), the default behavior for received exit messages causes the receiving actor to terminate for the same reason if the link has failed, i.e., terminated with a non-normal exit reason.
This allows developers to create a set of actors with the guarantee that either all or no actors are alive.
The default behavior can be overridden, i.e., exit message can be “trapped”.
When trapping exit messages, they are received as any other ordinary message and can be handled by the actor.
</p>
<!--TOC section id="sec12" First Steps-->
<h2 id="sec12" class="section">2 First Steps</h2><!--SEC END --><p>To compile CAF, you will need CMake and a C++11 compiler. To get and compile the sources, open a terminal (on Linux or Mac OS X) and type:</p><pre class="verbatim">git clone https://github.com/actor-framework/actor-framework
cd actor-framework
./configure
make
make install [as root, optional]
</pre><p>It is recommended to run the unit tests as well:</p><pre class="verbatim">make test
</pre><p>Please submit a bug report that includes (a) your compiler version, (b) your OS, and (c) the content of the file <span style="font-family:monospace">build/Testing/Temporary/LastTest.log</span> if an error occurs.</p>
<!--TOC subsection id="sec13" Features Overview-->
<h3 id="sec13" class="subsection">2.1 Features Overview</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
Lightweight, fast and efficient actor implementations
</li><li class="li-itemize">Network transparent messaging
</li><li class="li-itemize">Error handling based on Erlang’s failure model
</li><li class="li-itemize">Pattern matching for messages as internal DSL to ease development
</li><li class="li-itemize">Thread-mapped actors for soft migration of existing applications
</li><li class="li-itemize">Publish/subscribe group communication
</li></ul>
<!--TOC subsection id="sec14" Supported Compilers-->
<h3 id="sec14" class="subsection">2.2 Supported Compilers</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
GCC ≥ 4.7
</li><li class="li-itemize">Clang ≥ 3.2
</li></ul>
<!--TOC subsection id="sec15" Supported Operating Systems-->
<h3 id="sec15" class="subsection">2.3 Supported Operating Systems</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
Linux
</li><li class="li-itemize">Mac OS X
</li><li class="li-itemize"><span style="font-style:italic">Note for MS Windows</span>:
CAF relies on C++11 features such as unrestricted unions.
We will support this platform as soon as Microsoft’s compiler implements all required C++11 features.
In the meantime, CAF can be used with MinGW.
</li></ul>
<!--TOC subsection id="sec16" Hello World Example-->
<h3 id="sec16" class="subsection">2.4 Hello World Example</h3><!--SEC END --><div class="lstlisting"><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> <</span><span style="font-size:small">string</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> <</span><span style="font-size:small">iostream</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"caf/all.hpp"</span></span></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">namespace</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">namespace</span></span><span style="font-size:small"> </span><span style="font-size:small">caf</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">mirror</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// return the (initial) actor behavior</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// a handler for messages containing a single string</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// that replies with a string</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">what</span><span style="font-size:small">) -> </span><span style="font-size:small">string</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// prints "Hello World!" via aout</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// (thread-safe cout wrapper)</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small">what</span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// terminates this actor</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ('become' otherwise loops forever)</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// reply "!dlroW olleH"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">(</span><span style="font-size:small">what</span><span style="font-size:small">.</span><span style="font-size:small">rbegin</span><span style="font-size:small">(), </span><span style="font-size:small">what</span><span style="font-size:small">.</span><span style="font-size:small">rend</span><span style="font-size:small">());</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">hello_world</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">actor</span><span style="font-size:small">& </span><span style="font-size:small">buddy</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// send "Hello World!" to our buddy ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">buddy</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"Hello World!"</span></span></span><span style="font-size:small">).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... wait for a response ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">what</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... and print it</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small">what</span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// create a new actor that calls 'mirror()'</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">mirror_actor</span><span style="font-size:small"> = </span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">mirror</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// create another actor that calls 'hello_world(mirror_actor)';</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">hello_world</span><span style="font-size:small">, </span><span style="font-size:small">mirror_actor</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// wait until all other actors we have spawned are done</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// run cleanup code before exiting main</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">shutdown</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec17" Pattern Matching-->
<h2 id="sec17" class="section">3 Pattern Matching</h2><!--SEC END --><p>
<a id="Sec::PatternMatching"></a></p><p>Actor programming implies a message passing paradigm.
This means that defining message handlers is a recurring task.
The easiest and most natural way to specify such message handlers is pattern matching.
Unfortunately, C++ does not provide any pattern matching facilities.
Hence, we provide an internal domain-specific language to match incoming messages.</p>
<!--TOC subsection id="sec18" Basics-->
<h3 id="sec18" class="subsection">3.1 Basics</h3><!--SEC END --><p>
<a id="Sec::PatternMatching::Basics"></a></p><p>Actors can store a set of message callbacks using either <code>behavior</code> or <code>message_handler</code>.
The difference between the two is that the former stores an optional timeout.
The most basic way to define a pattern is to store a set of lambda expressions using one of the two container types.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">bhvr1</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">c</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>In our first example, <code>bhvr1</code> models a pattern accepting messages that consist of either exactly one <code><span style="color:blue">int</span></code>, or one <code><span style="color:blue">int</span></code> followed by a <code><span style="color:blue">float</span></code>, or three <code><span style="color:blue">int</span></code>s.
Any other message is not matched and will remain in the mailbox until it is consumed eventually.
This caching mechanism allows actors to ignore messages until a state change replaces its message handler.
However, this can lead to a memory leak if an actor receives messages it handles in no state.
To allow actors to specify a default message handlers for otherwise unmatched messages, CAF provides <code>others</code>.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">bhvr2</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">c</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [] { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>Please note the change in syntax for the default case.
The lambda expression passed to the constructor of <code>behavior</code> is prefixed by a ”match expression” and the operator <code>>></code>.</p>
<!--TOC subsection id="sec19" Atoms-->
<h3 id="sec19" class="subsection">3.2 Atoms</h3><!--SEC END --><p>
<a id="Sec::PatternMatching::Atoms"></a></p><p>Assume an actor provides a mathematical service for integers.
It takes two arguments, performs a predefined operation and returns the result.
It cannot determine an operation, such as multiply or add, by receiving two operands.
Thus, the operation must be encoded into the message.
The Erlang programming language introduced an approach to use non-numerical
constants, so-called <span style="font-style:italic">atoms</span>, which have an unambiguous, special-purpose type and do not have the runtime overhead of string constants.
Atoms are mapped to integer values at compile time in CAF.
This mapping is guaranteed to be collision-free and invertible, but limits atom literals to ten characters and prohibits special characters.
Legal characters are “<code>_0</code><code>-9</code><code>A</code><code>-</code><code>Za</code><code>-</code><code>z</code>” and the whitespace character.
Atoms are created using the <code><span style="color:blue">constexpr</span></code> function <code>atom</code>, as the following example illustrates.</p><div class="lstlisting"><span style="font-size:small">atom_value</span><span style="font-size:small"> </span><span style="font-size:small">a1</span><span style="font-size:small"> = </span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"add"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">atom_value</span><span style="font-size:small"> </span><span style="font-size:small">a2</span><span style="font-size:small"> = </span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"multiply"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span></div><p><span style="font-weight:bold">Warning</span>: The compiler cannot enforce the restrictions at compile time, except for a length check.
The assertion <code>atom</code><code>(</code><code><span style="color:#007F00"><code>"!?"</code></span></code><code>) != </code><code>atom</code><code>(</code><code><span style="color:#007F00"><code>"?!"</code></span></code><code>)</code> is not true, because each invalid character is mapped to the whitespace character.</p><p>An <code>atom_value</code> alone does not help us statically annotate function handlers.
To accomplish this, CAF offers compile-time <em>atom constants</em>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">add_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"add"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">multiply_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"multiply"</span></span></span><span style="font-size:small">)>;</span></div><p>Using the constants, we can now define message passing interfaces in a convenient way.
</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">do_math</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small">add_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small"> + </span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small">multiply_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small"> * </span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>Atom constants define a static member <code>value</code> that can be used on the caller side (see Section <a href="#Sec%3A%3ASend">5</a>), e.g., <code>send</code><code>(</code><code>math_actor</code><code>, </code><code>add_atom</code><code>::</code><code>value</code><code>, 1, 2)</code>.
Please note that the static <code>value</code> member does <em>not</em> have the type <code>atom_value</code>, unlike <code>std</code><code>::</code><code>integral_constant</code> for example.</p>
<!--TOC subsection id="sec20" Advanced Match Cases-->
<h3 id="sec20" class="subsection">3.3 Advanced Match Cases</h3><!--SEC END --><p>Match cases are an advanced feature of CAF and allow you to match on values and to transform data while matching.
A match case begins with a call to the function <code>on</code>, which returns an intermediate object providing <code><span style="color:blue">operator</span></code><code>>></code>.
The right-hand side of the operator denotes a callback, usually a lambda expression, that should be invoked if a tuple matches the types given to <code>on</code>,</p><p>When using the basic syntax, CAF generates the match case automatically.
A verbose version of the <code>bhvr1</code> from <a href="#Sec%3A%3APatternMatching%3A%3ABasics">3.1</a> is shown below.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">verbose_bhvr1</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">c</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>It is worth mentioning that passing the lambdas directly is more efficient, since it allows CAF to select a special-purpose implementation.
The function <code>on</code> can be used in two ways.
Either with template parameters only or with function parameters only.
The latter version deduces all types from its arguments and matches for both type and value.
To match for any value of a given type, the template <code>val</code><code><</code><code>T</code><code>></code> can be used, as shown in the following example.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">bhvr3</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small">(42) >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">i</span><span style="font-size:small"> == 42); },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"hello world"</span></span></span><span style="font-size:small">) >> [] { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"print"</span></span></span><span style="font-size:small">, </span><span style="font-size:small">val</span><span style="font-size:small"><</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">>) >> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">what</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p><span style="font-weight:bold">Note:</span> The given callback can have less arguments than the pattern.
But it is only allowed to skip arguments from left to right.</p><div class="lstlisting"><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> } </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ok</span></span></span><span style="font-size:small">
</span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> } </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ok</span></span></span><span style="font-size:small">
</span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> } </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ok</span></span></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> } </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// compiler error</span></span></span></div><p>To avoid redundancy when working with match expressions, <code>arg_match</code> can be used as last argument to the function <code>on</code>.
This causes the compiler to deduce all further types from the signature of any given callback.</p><div class="lstlisting"><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// is equal to:</span></span></span><span style="font-size:small">
</span><span style="font-size:small">on</span><span style="font-size:small">(</span><span style="font-size:small">arg_match</span><span style="font-size:small">) >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span></div><p>Note that <code>arg_match</code> must be passed as last parameter.
If all types should be deduced from the callback signature, <code>on_arg_match</code> can be used, which is a faster alternative for <code>on</code><code>(</code><code>arg_match</code><code>)</code>.
However, <code>on_arg_match</code> is used implicitly whenever a callback is used without preceding match expression.</p>
<!--TOC subsection id="sec21" Wildcards-->
<h3 id="sec21" class="subsection">3.4 Wildcards</h3><!--SEC END --><p>
<a id="Sec::PatternMatching::Wildcards"></a></p><p>The type <code>anything</code> can be used as wildcard to match any number of any types.
A pattern created by <code>on</code><code><</code><code>anything</code><code>>()</code> or its alias <code>others</code> is useful to define a default case.
For patterns defined without template parameters, the <code><span style="color:blue">constexpr</span></code> value <code>any_vals</code> can be used as function argument.
The constant <code>any_vals</code> is of type <code>anything</code> and is nothing but syntactic sugar for defining patterns.</p><div class="lstlisting"><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small">anything</span><span style="font-size:small">>() >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// tuple with int as first element</span></span></span><span style="font-size:small">
</span><span style="font-size:small">},</span><span style="font-size:small">
</span><span style="font-size:small">on</span><span style="font-size:small">(</span><span style="font-size:small">any_vals</span><span style="font-size:small">, </span><span style="font-size:small">arg_match</span><span style="font-size:small">) >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// tuple with int as last element</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// "on(any_vals, arg_match)" is equal to "on(anything{}, arg_match)"</span></span></span><span style="font-size:small">
</span><span style="font-size:small">},</span><span style="font-size:small">
</span><span style="font-size:small">others</span><span style="font-size:small"> >> [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// everything else (default handler)</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// "others" is equal to "on<anything>()" and "on(any_vals)"</span></span></span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC subsection id="sec22" Projections-->
<h3 id="sec22" class="subsection">3.5 Projections</h3><!--SEC END --><p>Projections perform type conversions or extract data from a given input.
If a callback expects an integer but the received message contains a string, a projection can be used to perform a type conversion on-the-fly.
This conversion must not have side-effects and must not throw exceptions.
A failed projection is not an error, it simply indicates that a pattern is not matched.
Let us have a look at a simple example.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">intproj</span><span style="font-size:small"> = [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) -> </span><span style="font-size:small">option</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">* </span><span style="font-size:small">endptr</span><span style="font-size:small"> = </span><span style="font-size:small"><span style="color:blue">nullptr</span></span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">result</span><span style="font-size:small"> = </span><span style="font-size:small"><span style="color:blue">static_cast</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>(</span><span style="font-size:small">strtol</span><span style="font-size:small">(</span><span style="font-size:small">str</span><span style="font-size:small">.</span><span style="font-size:small">c_str</span><span style="font-size:small">(), &</span><span style="font-size:small">endptr</span><span style="font-size:small">, 10));</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">endptr</span><span style="font-size:small"> != </span><span style="font-size:small"><span style="color:blue">nullptr</span></span><span style="font-size:small"> && *</span><span style="font-size:small">endptr</span><span style="font-size:small"> == </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">'\0'</span></span></span><span style="font-size:small">) </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">result</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {};</span><span style="font-size:small">
</span><span style="font-size:small">};</span><span style="font-size:small">
</span><span style="font-size:small">message_handler</span><span style="font-size:small"> </span><span style="font-size:small">fun</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small">(</span><span style="font-size:small">intproj</span><span style="font-size:small">) >> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// case 1: successfully converted a string</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// case 2: str is not an integer</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>The lambda <code>intproj</code> is a <code>string</code> ⇒ <code><span style="color:blue">int</span></code> projection, but note that it does not return an integer.
It returns <code>option</code><code><</code><code><span style="color:blue">int</span></code><code>></code>, because the projection is not guaranteed to always succeed.
An empty <code>option</code> indicates, that a value does not have a valid mapping to an integer.
A pattern does not match if a projection failed.</p><p><span style="font-weight:bold">Note</span>: Functors used as projection must take exactly one argument and must return a value.
The types for the pattern are deduced from the functor’s signature.
If the functor returns an <code>option</code><code><</code><code>T</code><code>></code>, then <code>T</code> is deduced.</p>
<!--TOC subsection id="sec23" Dynamically Building Messages-->
<h3 id="sec23" class="subsection">3.6 Dynamically Building Messages</h3><!--SEC END --><p>Usually, messages are created implicitly when sending messages but can also be created explicitly using <code>make_message</code>.
In both cases, types and number of elements are known at compile time.
To allow for fully dynamic message generation, CAF also offers a third option to create messages by using a <code>message_builder</code>:</p><div class="lstlisting"><span style="font-size:small">message_builder</span><span style="font-size:small"> </span><span style="font-size:small">mb</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// prefix message with some atom</span></span></span><span style="font-size:small">
</span><span style="font-size:small">mb</span><span style="font-size:small">.</span><span style="font-size:small">append</span><span style="font-size:small">(</span><span style="font-size:small">strings_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// fill message with some strings</span></span></span><span style="font-size:small">
</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">> </span><span style="font-size:small">strings</span><span style="font-size:small">{</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small">};</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">for</span></span><span style="font-size:small"> (</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small"> : </span><span style="font-size:small">strings</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">mb</span><span style="font-size:small">.</span><span style="font-size:small">append</span><span style="font-size:small">(</span><span style="font-size:small">str</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// create the message</span></span></span><span style="font-size:small">
</span><span style="font-size:small">message</span><span style="font-size:small"> </span><span style="font-size:small">msg</span><span style="font-size:small"> = </span><span style="font-size:small">mb</span><span style="font-size:small">.</span><span style="font-size:small">to_message</span><span style="font-size:small">();</span></div>
<!--TOC section id="sec24" Actors-->
<h2 id="sec24" class="section">4 Actors</h2><!--SEC END --><p>
<a id="Sec::Actors"></a></p><p>CAF provides several actor implementations, each covering a particular use case.
The class <code>local_actor</code> is the base class for all implementations, except for (remote) proxy actors.
Hence, <code>local_actor</code> provides a common interface for actor operations like trapping exit messages or finishing execution.
The default actor implementation in CAF is event-based.
Event-based actors have a very small memory footprint and are thus very lightweight and scalable.
Context-switching actors are used for actors that make use of the blocking API (see Section <a href="#Sec%3A%3ABlockingAPI">16</a>), but do not need to run in a separate thread.
Context-switching and event-based actors are scheduled cooperatively in a thread pool.
Thread-mapped actors can be used to opt-out of this cooperative scheduling.</p>
<!--TOC subsection id="sec25" Implicit <span style="font-family:monospace">self</span> Pointer-->
<h3 id="sec25" class="subsection">4.1 Implicit <span style="font-family:monospace">self</span> Pointer</h3><!--SEC END --><p>When using a function or functor to implement an actor, the first argument <em>can</em> be used to capture a pointer to the actor itself.
The type of this pointer is <code>event_based_actor</code><code>*</code> per default and <code>blocking_actor</code><code>*</code> when using the <code>blocking_api</code> flag.
When dealing with typed actors, the types are <code>typed_event_based_actor</code><code><...>*</code> and <code>typed_blocking_actor</code><code><...>*</code>.</p>
<!--TOC subsection id="sec26" Interface-->
<h3 id="sec26" class="subsection">4.2 Interface</h3><!--SEC END --><p>
<a id="Sec::Actors::Interfaces"></a></p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">local_actor</span><span style="font-size:small">;</span></div><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="vertical-align:middle;text-align:left;" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member functions</span></span><span style="font-size:small"> </span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Observers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">actor_addr</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">address</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the address of this actor </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">trap_exit</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Checks whether this actor traps exit messages </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">current_message</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the currently processed message<br>
</span><span style="font-size:small"><span style="font-weight:bold">Warning</span></span><span style="font-size:small">: Only set during callback invocation; calling this function after forwarding the message or while not in a callback is undefined behavior </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">actor_addr</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">current_sender</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the sender of the current message<br>
</span><span style="font-size:small"><span style="font-weight:bold">Warning</span></span><span style="font-size:small">: Only set during callback invocation; calling this function after forwarding the message or while not in a callback is undefined behavior </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">vector</span></code><code><span style="font-size:small"><</span></code><code><span style="font-size:small">group</span></code><code><span style="font-size:small">> </span></code><code><span style="font-size:small">joined_groups</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns all subscribed groups </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Modifiers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">quit</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">uint32_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">reason</span></code><code><span style="font-size:small"> = </span></code><code><span style="font-size:small">normal</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Finishes execution of this actor </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">trap_exit</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">enabled</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Enables or disables trapping of exit messages </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">join</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">group</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">g</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Subscribes to group </span><code><span style="font-size:small">g</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">leave</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">group</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">g</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Unsubscribes group </span><code><span style="font-size:small">g</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">on_sync_failure</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">auto</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">fun</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Sets a handler, i.e., a functor taking no arguments, for unexpected synchronous response messages (default action is to kill the actor for reason </span><code><span style="font-size:small">unhandled_sync_failure</span></code><span style="font-size:small">) </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">on_sync_timeout</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">auto</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">fun</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Sets a handler, i.e., a functor taking no arguments, for </span><code><span style="font-size:small">timed_sync_send</span></code><span style="font-size:small"> timeout messages (default action is to kill the actor for reason </span><code><span style="font-size:small">unhandled_sync_timeout</span></code><span style="font-size:small">) </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">monitor</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">actor</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">whom</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Unidirectionally monitors </span><code><span style="font-size:small">whom</span></code><span style="font-size:small"> (see Section </span><a href="#Sec%3A%3AManagement%3A%3AMonitors"><span style="font-size:small">8.2</span></a><span style="font-size:small">) </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">demonitor</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">actor</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">whom</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Removes a monitor from </span><code><span style="font-size:small">whom</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">has_sync_failure_handler</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Checks wheter this actor has a user-defined sync failure handler </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">F</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">set_exception_handler</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">F</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">f</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Sets a custom handler for uncaught exceptions </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
</table>
<!--TOC section id="sec27" Sending Messages-->
<h2 id="sec27" class="section">5 Sending Messages</h2><!--SEC END --><p>
<a id="Sec::Send"></a></p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Args</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">whom</span><span style="font-size:small">, </span><span style="font-size:small">Args</span><span style="font-size:small">&&... </span><span style="font-size:small">what</span><span style="font-size:small">);</span></div><p>Messages can be sent by using the member function <code>send</code>.
The variadic template parameter pack <code>what</code><code>...</code> is converted to a message and then enqueued to the mailbox of <code>whom</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">some_fun</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">other</span><span style="font-size:small"> = </span><span style="font-size:small">spawn</span><span style="font-size:small">(...);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">other</span><span style="font-size:small">, 1, 2, 3);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// sending a message directly is also ok:</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">msg</span><span style="font-size:small"> = </span><span style="font-size:small">make_message</span><span style="font-size:small">(1, 2, 3);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">other</span><span style="font-size:small">, </span><span style="font-size:small">msg</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC subsection id="sec28" Replying to Messages-->
<h3 id="sec28" class="subsection">5.1 Replying to Messages</h3><!--SEC END --><p>
<a id="Sec::Send::Reply"></a></p><p>The return value of a message handler is used as response message.
Actors can also use the result of a <code>sync_send</code> to answer to a request, as shown below.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">client</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">actor</span><span style="font-size:small">& </span><span style="font-size:small">master</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">request</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">master</span><span style="font-size:small">, </span><span style="font-size:small">request</span><span style="font-size:small">).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">response</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">response</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div>
<!--TOC subsection id="sec29" Delaying Messages-->
<h3 id="sec29" class="subsection">5.2 Delaying Messages</h3><!--SEC END --><p>Messages can be delayed by using the function <code>delayed_send</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">poll_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"poll"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">poller</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">seconds</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">delayed_send</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">seconds</span><span style="font-size:small">(1), </span><span style="font-size:small">poll_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small">poll_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// poll a resource</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// schedule next polling</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">delayed_send</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">seconds</span><span style="font-size:small">(1), </span><span style="font-size:small">poll_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC subsection id="sec30" Forwarding Messages in Untyped Actors-->
<h3 id="sec30" class="subsection">5.3 Forwarding Messages in Untyped Actors</h3><!--SEC END --><p>The member function <code>forward_to</code> forwards the last dequeued message to an other actor.
Forwarding a synchronous message will also transfer responsibility for the request, i.e., the receiver of the forwarded message can reply as usual and the original sender of the message will receive the response.
The following diagram illustrates forwarding of a synchronous message from actor <span style="font-family:monospace">B</span> to actor <span style="font-family:monospace">C</span>.</p><pre class="verbatim"><span style="font-size:small"> A B C
| | |
| --(sync_send)--> | |
| | --(forward_to)-> |
| X |---\
| | | compute
| | | result
| |<--/
| <-------------(reply)-------------- |
| X
|---\
| | handle
| | response
|<--/
|
X
</span></pre><p>The forwarding is completely transparent to actor <span style="font-family:monospace">C</span>, since it will see actor <span style="font-family:monospace">A</span> as sender of the message.
However, actor <span style="font-family:monospace">A</span> will see actor <span style="font-family:monospace">C</span> as sender of the response message instead of actor <span style="font-family:monospace">B</span> and thus could recognize the forwarding by evaluating <code>self</code><code>-></code><code>last_sender</code><code>()</code>.
</p>
<!--TOC section id="sec31" Receiving Messages-->
<h2 id="sec31" class="section">6 Receiving Messages</h2><!--SEC END --><p>
<a id="Sec::Receive"></a></p><p>The current <span style="font-style:italic">behavior</span> of an actor is its response to the <span style="font-style:italic">next</span> incoming message and includes (a) sending messages to other actors, (b) creation of more actors, and (c) setting a new behavior.</p><p>An event-based actor, i.e., the default implementation in CAF, uses <code>become</code> to set its behavior.
The given behavior is then executed until it is replaced by another call to <code>become</code> or the actor finishes execution.</p>
<!--TOC subsection id="sec32" Class-based actors-->
<h3 id="sec32" class="subsection">6.1 Class-based actors</h3><!--SEC END --><p>A class-based actor is a subtype of <code>event_based_actor</code> and must implement the pure virtual member function <code>make_behavior</code> returning the initial behavior.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">printer</span><span style="font-size:small"> : </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small"> </span><span style="font-size:small">event_based_actor</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">make_behavior</span><span style="font-size:small">() </span><span style="font-size:small"><span style="color:blue">override</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">cout</span><span style="font-size:small"> << </span><span style="font-size:small">to_string</span><span style="font-size:small">(</span><span style="font-size:small">last_dequeued</span><span style="font-size:small">()) << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>Another way to implement class-based actors is provided by the class <code>sb_actor</code> (“State-Based Actor”).
This base class simply returns <code>init_state</code> (defined in the subclass) from its implementation for <code>make_behavior</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">printer</span><span style="font-size:small"> : </span><span style="font-size:small">sb_actor</span><span style="font-size:small"><</span><span style="font-size:small">printer</span><span style="font-size:small">> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">init_state</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">cout</span><span style="font-size:small"> << </span><span style="font-size:small">to_string</span><span style="font-size:small">(</span><span style="font-size:small">last_dequeued</span><span style="font-size:small">()) << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>Note that <code>sb_actor</code> uses the Curiously Recurring Template Pattern. Thus, the derived class must be given as template parameter.
This technique allows <code>sb_actor</code> to access the <code>init_state</code> member of a derived class.
The following example illustrates a more advanced state-based actor that implements a stack with a fixed maximum number of elements.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">pop_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"pop"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">push_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"push"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">fixed_stack</span><span style="font-size:small"> : </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small"> </span><span style="font-size:small">sb_actor</span><span style="font-size:small"><</span><span style="font-size:small">fixed_stack</span><span style="font-size:small">> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small">:</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">fixed_stack</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">max</span><span style="font-size:small">) : </span><span style="font-size:small">max_size</span><span style="font-size:small">(</span><span style="font-size:small">max</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">full</span><span style="font-size:small">.</span><span style="font-size:small">assign</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">push_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* discard */</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">pop_atom</span><span style="font-size:small">) -> </span><span style="font-size:small">message</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">result</span><span style="font-size:small"> = </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">back</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">pop_back</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">become</span><span style="font-size:small">(</span><span style="font-size:small">filled</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">make_message</span><span style="font-size:small">(</span><span style="font-size:small">ok_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">, </span><span style="font-size:small">result</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">filled</span><span style="font-size:small">.</span><span style="font-size:small">assign</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">push_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">what</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">push_back</span><span style="font-size:small">(</span><span style="font-size:small">what</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">size</span><span style="font-size:small">() == </span><span style="font-size:small">max_size</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">become</span><span style="font-size:small">(</span><span style="font-size:small">full</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">pop_atom</span><span style="font-size:small">) -> </span><span style="font-size:small">message</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">result</span><span style="font-size:small"> = </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">back</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">pop_back</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">empty</span><span style="font-size:small">()) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">become</span><span style="font-size:small">(</span><span style="font-size:small">empty</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">make_message</span><span style="font-size:small">(</span><span style="font-size:small">ok_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">, </span><span style="font-size:small">result</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">empty</span><span style="font-size:small">.</span><span style="font-size:small">assign</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">push_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">what</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">data</span><span style="font-size:small">.</span><span style="font-size:small">push_back</span><span style="font-size:small">(</span><span style="font-size:small">what</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">become</span><span style="font-size:small">(</span><span style="font-size:small">filled</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">pop_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">error_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">max_size</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">> </span><span style="font-size:small">data</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">full</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">filled</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">empty</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">behavior</span><span style="font-size:small">& </span><span style="font-size:small">init_state</span><span style="font-size:small"> = </span><span style="font-size:small">empty</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div>
<!--TOC subsection id="sec33" Nesting Receives Using <code>become</code><code>/</code><code>unbecome</code>-->
<h3 id="sec33" class="subsection">6.2 Nesting Receives Using <code>become</code><code>/</code><code>unbecome</code></h3><!--SEC END --><p>Since <code>become</code> does not block, an actor has to manipulate its behavior stack to achieve nested receive operations.
An actor can set a new behavior by calling <code>become</code> with the <code>keep_behavior</code> policy to be able to return to its previous behavior later on by calling <code>unbecome</code>, as shown in the example below.</p><div class="lstlisting"><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// receives {int, float} sequences</span></span></span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">testee</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">value1</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// the keep_behavior policy stores the current behavior</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// on the behavior stack to be able to return to this</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// behavior later on by calling unbecome()</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">keep_behavior</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">value2</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">cout</span><span style="font-size:small"> << </span><span style="font-size:small">value1</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">" => "</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">value2</span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// restore previous behavior</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">unbecome</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div><p>An event-based actor finishes execution with normal exit reason if the behavior stack is empty after calling <code>unbecome</code>.
The default policy of <code>become</code> is <code>discard_behavior</code> that causes an actor to override its current behavior.
The policy flag must be the first argument of <code>become</code>.</p><p><span style="font-weight:bold">Note</span>: the message handling in CAF is consistent among all actor implementations: unmatched messages are <span style="font-style:italic">never</span> implicitly discarded if no suitable handler was found.
Hence, the order of arrival is not important in the example above.
This is unlike other event-based implementations of the actor model such as Akka for instance.</p>
<!--TOC subsection id="sec34" Timeouts-->
<h3 id="sec34" class="subsection">6.3 Timeouts</h3><!--SEC END --><p>
<a id="Sec::Receive::Timeouts"></a></p><p>A behavior set by <code>become</code> is invoked whenever a new messages arrives.
If no message ever arrives, the actor would wait forever.
This might be desirable if the actor only provides a service and should not do anything else.
But often, we need to be able to recover if an expected messages does not arrive within a certain time period. The following examples illustrates the usage of <code>after</code> to define a timeout.</p><div class="lstlisting"><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">eager_actor</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [] { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">after</span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">seconds</span><span style="font-size:small">(10)) >> [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"received nothing within 10 seconds..."</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div><p>Callbacks given as timeout handler must have zero arguments.
Any number of patterns can precede the timeout definition, but “<code>after</code>” must always be the final statement.
Using a zero-duration timeout causes the actor to scan its mailbox once and then invoke the timeout immediately if no matching message was found.</p><p>CAF supports timeouts using <code>minutes</code>, <code>seconds</code>, <code>milliseconds</code> and <code>microseconds</code>.
However, note that the precision depends on the operating system and your local work load.
Thus, you should not depend on a certain clock resolution.</p>
<!--TOC subsection id="sec35" Skipping Messages-->
<h3 id="sec35" class="subsection">6.4 Skipping Messages</h3><!--SEC END --><p>Unmatched messages are skipped automatically by CAF’s runtime system.
This is true for <span style="font-style:italic">all</span> actor implementations.
To allow actors to skip messages manually, <code>skip_message</code> can be used.
This is in particular useful whenever an actor switches between behaviors, but wants to use a default rule created by <code>others</code> to catch messages that are not handled by any of its behaviors.</p><p>The following example illustrates a simple server actor that dispatches requests to workers.
After receiving an <code><span style="color:#007F00"><code>'idle'</code></span></code> message, it awaits a request that is then forwarded to the idle worker.
Afterwards, the server returns to its initial behavior, i.e., awaits the next <code><span style="color:#007F00"><code>'idle'</code></span></code> message.
The server actor will exit for reason <code>user_defined</code> whenever it receives a message that is neither a request, nor an idle message.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">idle_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"idle"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">request_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"request"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">server</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">die</span><span style="font-size:small"> = [=] { </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">(</span><span style="font-size:small">exit_reason</span><span style="font-size:small">::</span><span style="font-size:small">user_defined</span><span style="font-size:small">); };</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">idle_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">worker</span><span style="font-size:small"> = </span><span style="font-size:small">last_sender</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">keep_behavior</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">request_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// forward request to idle worker</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">forward_to</span><span style="font-size:small">(</span><span style="font-size:small">worker</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// await next idle message</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">unbecome</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">idle_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">skip_message</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> </span><span style="font-size:small">die</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">request_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">skip_message</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> </span><span style="font-size:small">die</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec36" Synchronous Communication-->
<h2 id="sec36" class="section">7 Synchronous Communication</h2><!--SEC END --><p>
<a id="Sec::Sync"></a></p><p>CAF supports both asynchronous and synchronous communication.
The member function <code>sync_send</code> sends synchronous request messages.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Args</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">__unspecified__</span><span style="font-size:small"> </span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">whom</span><span style="font-size:small">, </span><span style="font-size:small">Args</span><span style="font-size:small">&&... </span><span style="font-size:small">what</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">Duration</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Args</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">__unspecified__</span><span style="font-size:small"> </span><span style="font-size:small">timed_sync_send</span><span style="font-size:small">(</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">whom</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">Duration</span><span style="font-size:small"> </span><span style="font-size:small">timeout</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">Args</span><span style="font-size:small">&&... </span><span style="font-size:small">what</span><span style="font-size:small">);</span></div><p>A synchronous message is sent to the receiving actor’s mailbox like any other (asynchronous) message.
The response message, on the other hand, is treated separately.</p><p>The difference between <code>sync_send</code> and <code>timed_sync_send</code> is how timeouts are handled.
The behavior of <code>sync_send</code> is analogous to <code>send</code>, i.e., timeouts are specified by using <code>after</code><code>(...)</code> statements (see Section <a href="#Sec%3A%3AReceive%3A%3ATimeouts">6.3</a>).
When using <code>timed_sync_send</code> function, <code>after</code><code>(...)</code> statements are ignored and the actor will receive a <code>sync_timeout_msg</code> after the given duration instead.</p>
<!--TOC subsection id="sec37" Error Messages-->
<h3 id="sec37" class="subsection">7.1 Error Messages</h3><!--SEC END --><p>When using synchronous messaging, CAF’s runtime environment will send ...</p><ul class="itemize"><li class="li-itemize">
if the receiver is not alive:<br>
<code>sync_exited_msg</code><code> { </code><code>actor_addr</code><code> </code><code>source</code><code>; </code><code>std</code><code>::</code><code><span style="color:blue">uint32_t</span></code><code> </code><code>reason</code><code>; };</code>
</li><li class="li-itemize">if a message send by <code>timed_sync_send</code> timed out: <code>sync_timeout_msg</code>
</li></ul>
<!--TOC subsection id="sec38" Receive Response Messages-->
<h3 id="sec38" class="subsection">7.2 Receive Response Messages</h3><!--SEC END --><p>When sending a synchronous message, the response handler can be passed by either using <code>then</code> (event-based actors) or <code>await</code> (blocking actors).</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">foo</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">testee</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// testee replies with a string to 'get'</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">get_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// handle str</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">after</span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">seconds</span><span style="font-size:small">(30)) >> [=]() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// handle error</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div><p>Similar to <code>become</code>, the <code>then</code> function modifies an actor’s behavior stack.
However, it is used as “one-shot handler” and automatically returns to the previous behavior afterwards.</p>
<!--TOC subsection id="sec39" Synchronous Failures and Error Handlers-->
<h3 id="sec39" class="subsection">7.3 Synchronous Failures and Error Handlers</h3><!--SEC END --><p>An unexpected response message, i.e., a message that is not handled by given behavior, will invoke the actor’s <code>on_sync_failure</code> handler.
The default handler kills the actor by calling <code>self</code><code>-></code><code>quit</code><code>(</code><code>exit_reason</code><code>::</code><code>unhandled_sync_failure</code><code>)</code>.
The handler can be overridden by calling <code>self</code><code>-></code><code>on_sync_failure</code><code>(</code><code><span style="color:#7F007F"><code>/*...*/</code></span></code><code>)</code>.</p><p>Unhandled timeout messages trigger the <code>on_sync_timeout</code> handler.
The default handler kills the actor for reason <code>exit_reason</code><code>::</code><code>unhandled_sync_failure</code>.
It is possible set both error handlers by calling <code>self</code><code>-></code><code>on_sync_timeout_or_failure</code><code>(</code><code><span style="color:#7F007F"><code>/*...*)</code></span></code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">foo</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">testee</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// testee replies with a string to 'get'</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// set handler for unexpected messages</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">on_sync_failure</span><span style="font-size:small"> = [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"received: "</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">to_string</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">last_dequeued</span><span style="font-size:small">()) << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// set handler for timeouts</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">on_sync_timeout</span><span style="font-size:small"> = [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"timeout occured"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// set response handler by using "then"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">timed_sync_send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">seconds</span><span style="font-size:small">(30), </span><span style="font-size:small">get_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* handle str */</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span></div>
<!--TOC section id="sec40" Management & Error Detection-->
<h2 id="sec40" class="section">8 Management & Error Detection</h2><!--SEC END --><p>CAF adapts Erlang’s well-established fault propagation model.
It allows to build actor subsystem in which either all actors are alive or have collectively failed.</p>
<!--TOC subsection id="sec41" Links-->
<h3 id="sec41" class="subsection">8.1 Links</h3><!--SEC END --><p>Linked actors monitor each other.
An actor sends an exit message to all of its links as part of its termination.
The default behavior for actors receiving such an exit message is to die for the same reason, if the exit reason is non-normal.
Actors can <span style="font-style:italic">trap</span> exit messages to handle them manually.</p><div class="lstlisting"><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">worker</span><span style="font-size:small"> = ...;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// receive exit messages as regular messages</span></span></span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">trap_exit</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">true</span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// monitor spawned actor</span></span></span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">link_to</span><span style="font-size:small">(</span><span style="font-size:small">worker</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// wait until worker exited</span></span></span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">exit_msg</span><span style="font-size:small">& </span><span style="font-size:small">e</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">e</span><span style="font-size:small">.</span><span style="font-size:small">reason</span><span style="font-size:small"> == </span><span style="font-size:small">exit_reason</span><span style="font-size:small">::</span><span style="font-size:small">normal</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// worker finished computation</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">else</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// worker died unexpectedly</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div>
<!--TOC subsection id="sec42" Monitors-->
<h3 id="sec42" class="subsection">8.2 Monitors</h3><!--SEC END --><p>
<a id="Sec::Management::Monitors"></a></p><p>A monitor observes the lifetime of an actor.
Monitored actors send a down message to all observers as part of their termination.
Unlike exit messages, down messages are always treated like any other ordinary message.
An actor will receive one down message for each time it called <code>self</code><code>-></code><code>monitor</code><code>(...)</code>, even if it adds a monitor to the same actor multiple times.</p><div class="lstlisting"><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">worker</span><span style="font-size:small"> = ...;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// monitor spawned actor</span></span></span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">monitor</span><span style="font-size:small">(</span><span style="font-size:small">worker</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// wait until worker exited</span></span></span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">down_msg</span><span style="font-size:small">& </span><span style="font-size:small">d</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">d</span><span style="font-size:small">.</span><span style="font-size:small">reason</span><span style="font-size:small"> == </span><span style="font-size:small">exit_reason</span><span style="font-size:small">::</span><span style="font-size:small">normal</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// worker finished computation</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> } </span><span style="font-size:small"><span style="color:blue">else</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// worker died unexpectedly</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div>
<!--TOC subsection id="sec43" Error Codes-->
<h3 id="sec43" class="subsection">8.3 Error Codes</h3><!--SEC END --><p>All error codes are defined in the namespace <code>caf</code><code>::</code><code>exit_reason</code>.
To obtain a string representation of an error code, use <code>caf</code><code>::</code><code>exit_reason</code><code>::</code><code>as_string</code><code>(</code><code><span style="color:blue">uint32_t</span></code><code>)</code>.</p><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>normal</code></td><td style="vertical-align:middle;text-align:left;" >1</td><td style="vertical-align:middle;text-align:left;" >Actor finished execution without error </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>unhandled_exception</code></td><td style="vertical-align:middle;text-align:left;" >2</td><td style="vertical-align:middle;text-align:left;" >Actor was killed due to an unhandled exception </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>unhandled_sync_failure</code></td><td style="vertical-align:middle;text-align:left;" >4</td><td style="vertical-align:middle;text-align:left;" >Actor was killed due to an unexpected synchronous response message </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>unhandled_sync_timeout</code></td><td style="vertical-align:middle;text-align:left;" >5</td><td style="vertical-align:middle;text-align:left;" >Actor was killed, because no timeout handler was set and a synchronous message timed out </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>unknown</code></td><td style="vertical-align:middle;text-align:left;" >6</td><td style="vertical-align:middle;text-align:left;" >Indicates that an actor has been exited and its state is no longer known </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>user_shutdown</code></td><td style="vertical-align:middle;text-align:left;" >16</td><td style="vertical-align:middle;text-align:left;" >Actor was killed by a user-generated event </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>remote_link_unreachable</code></td><td style="vertical-align:middle;text-align:left;" >257</td><td style="vertical-align:middle;text-align:left;" >Indicates that a remote actor became unreachable, e.g., due to connection error </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>user_defined</code></td><td style="vertical-align:middle;text-align:left;" >65536</td><td style="vertical-align:middle;text-align:left;" >Minimum value for user-defined exit codes </td></tr>
<tr><td class="hbar" colspan=3></td></tr>
</table>
<!--TOC subsection id="sec44" Attach Cleanup Code to an Actor-->
<h3 id="sec44" class="subsection">8.4 Attach Cleanup Code to an Actor</h3><!--SEC END --><p>Actors can attach cleanup code to other actors.
This code is executed immediately if the actor has already exited.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">done_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"done"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">supervisor</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">worker</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">observer</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// "monitor" spawned actor</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">worker</span><span style="font-size:small">-></span><span style="font-size:small">attach_functor</span><span style="font-size:small">([</span><span style="font-size:small">observer</span><span style="font-size:small">](</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small"><span style="color:blue">uint32_t</span></span><span style="font-size:small"> </span><span style="font-size:small">reason</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// this callback is invoked from worker</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">anon_send</span><span style="font-size:small">(</span><span style="font-size:small">observer</span><span style="font-size:small">, </span><span style="font-size:small">done_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// wait until worker exited</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small">done_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... worker terminated ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div><p><span style="font-weight:bold">Note</span>: It is possible to attach code to remote actors, but the cleanup code will run on the local machine.
</p>
<!--TOC section id="sec45" Spawning Actors-->
<h2 id="sec45" class="section">9 Spawning Actors</h2><!--SEC END --><p>Actors are created using the function <code>spawn</code>.
The easiest way to implement actors is to use functors, e.g., a free function or a lambda expression.
The arguments to the functor are passed to <code>spawn</code> as additional arguments.
The function <code>spawn</code> also takes optional flags as template parameter.
The flag <code>detached</code> causes <code>spawn</code> to assign a dedicated thread to the actor, i.e., to opt-out of the cooperative scheduling.
Convenience flags like <code>linked</code> or <code>monitored</code> automatically link or monitor to the newly created actor.
Naturally, these two flags are not available on “top-level” spawns.
Actors that make use of the blocking API—see Section <a href="#Sec%3A%3ABlockingAPI">16</a>—must be spawned using the flag <code>blocking_api</code>.
Flags are concatenated using the operator <code>+</code>, as shown in the examples below.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"caf/all.hpp"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">namespace</span></span><span style="font-size:small"> </span><span style="font-size:small">caf</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor1</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor2</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">*, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">arg1</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">arg2</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">ugly_duckling</span><span style="font-size:small">(</span><span style="font-size:small">blocking_actor</span><span style="font-size:small">*);</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor3</span><span style="font-size:small"> : </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small"> </span><span style="font-size:small">event_based_actor</span><span style="font-size:small"> { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor4</span><span style="font-size:small"> : </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small"> </span><span style="font-size:small">event_based_actor</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small">: </span><span style="font-size:small">my_actor4</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">some_value</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small">
</span><span style="font-size:small">};</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// whenever we want to link to or monitor a spawned actor,</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// we have to spawn it using the self pointer, otherwise</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// we can use the free function 'spawn' (top-level spawn)</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">server</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn functor-based actors</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a0</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">my_actor1</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a1</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">linked</span><span style="font-size:small">>(</span><span style="font-size:small">my_actor2</span><span style="font-size:small">, 42, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"hello actor"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a2</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">monitored</span><span style="font-size:small">>([] { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a3</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small">([](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> }, 42);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn thread-mapped actors</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a4</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">detached</span><span style="font-size:small">>(</span><span style="font-size:small">my_actor1</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a5</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">detached</span><span style="font-size:small"> + </span><span style="font-size:small">linked</span><span style="font-size:small">>([] { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a6</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">detached</span><span style="font-size:small">>(</span><span style="font-size:small">my_actor2</span><span style="font-size:small">, 0, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"zero"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn class-based actors</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a7</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">my_actor3</span><span style="font-size:small">>();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a8</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">my_actor4</span><span style="font-size:small">, </span><span style="font-size:small">monitored</span><span style="font-size:small">>(42);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn and detach class-based actors</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a9</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">my_actor4</span><span style="font-size:small">, </span><span style="font-size:small">detached</span><span style="font-size:small">>(42);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn actors that need access to the blocking API</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">aa</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">blocking_api</span><span style="font-size:small">>(</span><span style="font-size:small">ugly_duckling</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// compiler error: my_actor2 captures the implicit</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// self pointer as event_based_actor* and thus cannot</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// be spawned using the `blocking_api` flag</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// --- auto ab = self->spawn<blocking_api>(my_actor2);</span></span></span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec46" Message Priorities-->
<h2 id="sec46" class="section">10 Message Priorities</h2><!--SEC END --><p>By default, all messages have the same priority and actors ignore priority flags.
Actors that should evaluate priorities must be spawned using the <code>priority_aware</code> flag.
This flag causes the actor to use a priority-aware mailbox implementation.
It is not possible to change this implementation dynamically at runtime.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">a_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"a"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">b_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"b"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">behavior</span><span style="font-size:small"> </span><span style="font-size:small">testee</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// send 'b' with normal priority</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">b_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// send 'a' with high priority</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">message_priority</span><span style="font-size:small">::</span><span style="font-size:small">high</span><span style="font-size:small">, </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">a_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// terminate after receiving a 'b'</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">b_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"received 'b' => quit"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">a_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"received 'a'"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// will print "received 'b' => quit"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// will print "received 'a'" and then "received 'b' => quit"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">priority_aware</span><span style="font-size:small">>(</span><span style="font-size:small">testee</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">shutdown</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec47" Network Transparency-->
<h2 id="sec47" class="section">11 Network Transparency</h2><!--SEC END --><p>All actor operations as well as sending messages are network transparent.
Remote actors are represented by actor proxies that forward all messages.
All functions shown in this section can be accessed by including the header <code><span style="color:#007F00"><code>"caf/io/all.hpp"</code></span></code> and live in the namespace <code>caf</code><code>::</code><code>io</code>.</p>
<!--TOC subsection id="sec48" Publishing of Actors-->
<h3 id="sec48" class="subsection">11.1 Publishing of Actors</h3><!--SEC END --><div class="lstlisting"><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">publish</span><span style="font-size:small">(</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">whom</span><span style="font-size:small">, </span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">* </span><span style="font-size:small">addr</span><span style="font-size:small"> = </span><span style="font-size:small"><span style="color:blue">nullptr</span></span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">bool</span></span><span style="font-size:small"> </span><span style="font-size:small">reuse_addr</span><span style="font-size:small"> = </span><span style="font-size:small"><span style="color:blue">false</span></span><span style="font-size:small">)</span></div><p>The function <code>publish</code> binds an actor to a given port.
To choose the next high-level port available for binding, one can specify <code>port</code><code> == 0</code> and retrieves the bound port as return value.
The return value is equal to <code>port</code> if <code>port</code><code> != 0</code>.
The function throws <code>network_error</code> if socket related errors occur or <code>bind_failure</code> if the specified port is already in use.
The optional <code>addr</code> parameter can be used to listen only to the given address.
Otherwise, the actor accepts all incoming connections (<code>INADDR_ANY</code>).
The flag <code>reuse_addr</code> controls the behavior when binding an IP
address to a port, with the same semantics as the BSD socket flag <code>SO_REUSEADDR</code>.
For example, if <code>reuse_addr</code><code> = </code><code><span style="color:blue">false</span></code>, binding two sockets to 0.0.0.0:42 and 10.0.0.1:42 will fail with <span style="font-family:monospace">EADDRINUSE</span> since 0.0.0.0 includes 10.0.0.1.
With <code>reuse_addr</code><code> = </code><code><span style="color:blue">true</span></code> binding would succeed because 10.0.0.1 and
0.0.0.0 are not literally equal addresses.</p><div class="lstlisting"><span style="font-size:small">publish</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">, 4242);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small">ping_atom</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">make_tuple</span><span style="font-size:small">(</span><span style="font-size:small">pong_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">, </span><span style="font-size:small">i</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div><p>To close a socket, e.g., to allow other actors to be published at the port, the function <code>unpublish</code> can be used.
This function is called implicitly if a published actor terminates.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">unpublish</span><span style="font-size:small">(</span><span style="font-size:small">caf</span><span style="font-size:small">::</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">whom</span><span style="font-size:small">, </span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">)</span></div>
<!--TOC subsection id="sec49" Connecting to Remote Actors-->
<h3 id="sec49" class="subsection">11.2 Connecting to Remote Actors</h3><!--SEC END --><div class="lstlisting"><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">remote_actor</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">* </span><span style="font-size:small">host</span><span style="font-size:small">, </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">)</span></div><p>The function <code>remote_actor</code> connects to the actor at given host and port.
A <code>network_error</code> is thrown if the connection failed.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">pong</span><span style="font-size:small"> = </span><span style="font-size:small">remote_actor</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"localhost"</span></span></span><span style="font-size:small">, 4242);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">pong</span><span style="font-size:small">, </span><span style="font-size:small">ping_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">, 0);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">become</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small">pong_value</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">i</span><span style="font-size:small"> >= 10) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">pong</span><span style="font-size:small">, </span><span style="font-size:small">ping_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">, </span><span style="font-size:small">i</span><span style="font-size:small"> + 1);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div>
<!--TOC section id="sec50" Network IO-->
<h2 id="sec50" class="section">12 Network IO</h2><!--SEC END --><p>
<a id="Sec::NetworkIO"></a></p><p>When communicating to other services in the network, sometimes low-level socket IO is inevitable.
For this reason, CAF provides <em>brokers</em>.
A broker is an event-based actor running in the middleman that multiplexes socket IO.
It can maintain any number of acceptors and connections.
Since the broker runs in the middleman, implementations should be careful to consume as little time as possible in message handlers.
Any considerable amount work should outsourced by spawning new actors (or maintaining worker actors).
All functions shown in this section can be accessed by including the header <code><span style="color:#007F00"><code>"caf/io/all.hpp"</code></span></code> and live in the namespace <code>caf</code><code>::</code><code>io</code>.</p>
<!--TOC subsection id="sec51" Spawning Brokers-->
<h3 id="sec51" class="subsection">12.1 Spawning Brokers</h3><!--SEC END --><p>Brokers are spawned using the function <code>spawn_io</code> and always use functor-based implementations capturing the self pointer of type <code>broker</code><code>*</code>.
For convenience, <code>spawn_io_server</code> can be used to spawn a new broker listening to a local port and <code>spawn_io_client</code> can be used to spawn a new broker that connects to given host and port or uses existing IO streams.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small">spawn_options</span><span style="font-size:small"> </span><span style="font-size:small">Os</span><span style="font-size:small"> = </span><span style="font-size:small">no_spawn_options</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">F</span><span style="font-size:small"> = </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">function</span><span style="font-size:small"><</span><span style="font-size:small">behavior</span><span style="font-size:small"> (</span><span style="font-size:small">broker</span><span style="font-size:small">*)>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Ts</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">spawn_io</span><span style="font-size:small">(</span><span style="font-size:small">F</span><span style="font-size:small"> </span><span style="font-size:small">fun</span><span style="font-size:small">, </span><span style="font-size:small">Ts</span><span style="font-size:small">&&... </span><span style="font-size:small">args</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small">spawn_options</span><span style="font-size:small"> </span><span style="font-size:small">Os</span><span style="font-size:small"> = </span><span style="font-size:small">no_spawn_options</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">F</span><span style="font-size:small"> = </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">function</span><span style="font-size:small"><</span><span style="font-size:small">behavior</span><span style="font-size:small"> (</span><span style="font-size:small">broker</span><span style="font-size:small">*)>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Ts</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">spawn_io_client</span><span style="font-size:small">(</span><span style="font-size:small">F</span><span style="font-size:small"> </span><span style="font-size:small">fun</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">input_stream_ptr</span><span style="font-size:small"> </span><span style="font-size:small">in</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">output_stream_ptr</span><span style="font-size:small"> </span><span style="font-size:small">out</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">Ts</span><span style="font-size:small">&&... </span><span style="font-size:small">args</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small">spawn_options</span><span style="font-size:small"> </span><span style="font-size:small">Os</span><span style="font-size:small"> = </span><span style="font-size:small">no_spawn_options</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">F</span><span style="font-size:small"> = </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">function</span><span style="font-size:small"><</span><span style="font-size:small">behavior</span><span style="font-size:small"> (</span><span style="font-size:small">broker</span><span style="font-size:small">*)>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Ts</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">spawn_io_client</span><span style="font-size:small">(</span><span style="font-size:small">F</span><span style="font-size:small"> </span><span style="font-size:small">fun</span><span style="font-size:small">, </span><span style="font-size:small">string</span><span style="font-size:small"> </span><span style="font-size:small">host</span><span style="font-size:small">, </span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">, </span><span style="font-size:small">Ts</span><span style="font-size:small">&&... </span><span style="font-size:small">args</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small">spawn_options</span><span style="font-size:small"> </span><span style="font-size:small">Os</span><span style="font-size:small"> = </span><span style="font-size:small">no_spawn_options</span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">F</span><span style="font-size:small"> = </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">function</span><span style="font-size:small"><</span><span style="font-size:small">behavior</span><span style="font-size:small"> (</span><span style="font-size:small">broker</span><span style="font-size:small">*)>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small">... </span><span style="font-size:small">Ts</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">spawn_io_server</span><span style="font-size:small">(</span><span style="font-size:small">F</span><span style="font-size:small"> </span><span style="font-size:small">fun</span><span style="font-size:small">, </span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">, </span><span style="font-size:small">Ts</span><span style="font-size:small">&&... </span><span style="font-size:small">args</span><span style="font-size:small">);</span></div>
<!--TOC subsection id="sec52" Broker Interface-->
<h3 id="sec52" class="subsection">12.2 Broker Interface</h3><!--SEC END --><p>
<a id="Sec::NetworkIO::BrokerInterface"></a></p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">broker</span><span style="font-size:small">;</span></div><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="vertical-align:middle;text-align:left;" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member Functions</span></span><span style="font-size:small"> </span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">configure_read</span></code><code><span style="font-size:small">(</span></code><span style="font-size:small"> </span><code><span style="font-size:small">connection_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">,</span></code><span style="font-size:small"> </span><code><span style="font-size:small">receive_policy</span></code><code><span style="font-size:small">::</span></code><code><span style="font-size:small">config</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">config</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Modifies the receive policy for the connection identified by </span><code><span style="font-size:small">hdl</span></code><span style="font-size:small">. This will cause the middleman to enqueue the next </span><code><span style="font-size:small">new_data_msg</span></code><span style="font-size:small"> according to the given </span><code><span style="font-size:small">config</span></code><span style="font-size:small"> created by </span><code><span style="font-size:small">receive_policy</span></code><code><span style="font-size:small">::</span></code><code><span style="font-size:small">exactly</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">x</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small">, </span><code><span style="font-size:small">receive_policy</span></code><code><span style="font-size:small">::</span></code><code><span style="font-size:small">at_most</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">x</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small">, or </span><code><span style="font-size:small">receive_policy</span></code><code><span style="font-size:small">::</span></code><code><span style="font-size:small">at_least</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">x</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> (with </span><code><span style="font-size:small">x</span></code><span style="font-size:small"> denoting the number of bytes) </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">write</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">connection_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">,</span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">num_bytes</span></code><code><span style="font-size:small">,</span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small">* </span></code><code><span style="font-size:small">buf</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Writes data to the output buffer </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">flush</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">connection_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Sends the data from the output buffer </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">F</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small">... </span></code><code><span style="font-size:small">Ts</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">actor</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">fork</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">F</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">fun</span></code><code><span style="font-size:small">,</span></code><span style="font-size:small"> </span><code><span style="font-size:small">connection_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">Ts</span></code><code><span style="font-size:small">&&... </span></code><code><span style="font-size:small">args</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Spawns a new broker that takes ownership of given connection </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">num_connections</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the number of open connections </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">close</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">connection_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Closes a connection </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">close</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">accept_handle</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">hdl</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Closes an acceptor </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
</table>
<!--TOC subsection id="sec53" Broker-related Message Types-->
<h3 id="sec53" class="subsection">12.3 Broker-related Message Types</h3><!--SEC END --><p>Brokers receive system messages directly from the middleman whenever an event on one of it handles occurs.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">new_connection_msg</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">accept_handle</span><span style="font-size:small"> </span><span style="font-size:small">source</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">connection_handle</span><span style="font-size:small"> </span><span style="font-size:small">handle</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>Whenever a new incoming connection (identified by the <code>handle</code> field) has been accepted for one of the broker’s accept handles, it will receive a <code>new_connection_msg</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">new_data_msg</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">connection_handle</span><span style="font-size:small"> </span><span style="font-size:small">handle</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">> </span><span style="font-size:small">buf</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>New incoming data is transmitted to the broker using messages of type <code>new_data_msg</code>.
The raw bytes can be accessed as buffer object of type <code>std</code><code>::</code><code>vector</code><code><</code><code><span style="color:blue">char</span></code><code>></code>.
The amount of data, i.e., how often this message is received, can be controlled using <code>configure_read</code> (see <a href="#Sec%3A%3ANetworkIO%3A%3ABrokerInterface">12.2</a>).
It is worth mentioning that the buffer is re-used whenever possible.
This means, as long as the broker does not create any new references to the message by copying it, the middleman will always use only a single buffer per connection.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">connection_closed_msg</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">connection_handle</span><span style="font-size:small"> </span><span style="font-size:small">handle</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">acceptor_closed_msg</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">accept_handle</span><span style="font-size:small"> </span><span style="font-size:small">handle</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><p>A <code>connection_closed_msg</code> or <code> </code><code>acceptor_closed_msg</code> informs the broker that one of it handles is no longer valid.
</p>
<!--TOC section id="sec54" Group Communication-->
<h2 id="sec54" class="section">13 Group Communication</h2><!--SEC END --><p>
<a id="Sec::Group"></a></p><p>CAF supports publish/subscribe-based group communication.
Actors can join and leave groups and send messages to groups.</p><div class="lstlisting"><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small"> </span><span style="font-size:small">group_module</span><span style="font-size:small"> = ...;</span><span style="font-size:small">
</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small"> </span><span style="font-size:small">group_id</span><span style="font-size:small"> = ...;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">grp</span><span style="font-size:small"> = </span><span style="font-size:small">group</span><span style="font-size:small">::</span><span style="font-size:small">get</span><span style="font-size:small">(</span><span style="font-size:small">group_module</span><span style="font-size:small">, </span><span style="font-size:small">group_id</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">join</span><span style="font-size:small">(</span><span style="font-size:small">grp</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">grp</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"test"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">leave</span><span style="font-size:small">(</span><span style="font-size:small">grp</span><span style="font-size:small">);</span></div>
<!--TOC subsection id="sec55" Anonymous Groups-->
<h3 id="sec55" class="subsection">13.1 Anonymous Groups</h3><!--SEC END --><p>
<a id="Sec::Group::Anonymous"></a></p><p>Groups created on-the-fly with <code>group</code><code>::</code><code>anonymous</code><code>()</code> can be used to coordinate a set of workers.
Each call to <code>group</code><code>::</code><code>anonymous</code><code>()</code> returns a new, unique group instance.</p>
<!--TOC subsection id="sec56" Local Groups-->
<h3 id="sec56" class="subsection">13.2 Local Groups</h3><!--SEC END --><p>
<a id="Sec::Group::Local"></a></p><p>The <code><span style="color:#007F00"><code>"local"</code></span></code> group module creates groups for in-process communication.
For example, a group for GUI related events could be identified by <code>group</code><code>::</code><code>get</code><code>(</code><code><span style="color:#007F00"><code>"local"</code></span></code><code>, </code><code><span style="color:#007F00"><code>"GUI events"</code></span></code><code>)</code>.
The group ID <code><span style="color:#007F00"><code>"GUI events"</code></span></code> uniquely identifies a singleton group instance of the module <code><span style="color:#007F00"><code>"local"</code></span></code>.</p>
<!--TOC subsection id="sec57" Remote Groups-->
<h3 id="sec57" class="subsection">13.3 Remote Groups</h3><!--SEC END --><p>
<a id="Sec::Group::RemoteGroups"></a></p><p>To deploy groups in a network, one host can act as group server by publishing its local groups at any given port:</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">publish_local_groups</span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">* </span><span style="font-size:small">addr</span><span style="font-size:small">)</span></div><p>By calling <code>group</code><code>::</code><code>get</code><code>(</code><code><span style="color:#007F00"><code>"remote"</code></span></code><code>, </code><code><span style="color:#007F00"><code>"<group>@<host>:<port>"</code></span></code><code>)</code>, other hosts are now able to connect to a remotely running group.
Please note that the group communication is no longer available once the server disconnects.
This implementation uses N-times unicast underneath.
It is worth mentioning that user-implemented groups can be build on top of IP multicast or overlay technologies such as Scribe to achieve better performance or reliability.</p>
<!--TOC subsection id="sec58" Spawning Actors in Groups-->
<h3 id="sec58" class="subsection">13.4 Spawning Actors in Groups</h3><!--SEC END --><p>
<a id="Sec::Group::Spawn"></a></p><p>The function <code>spawn_in_group</code> can be used to create actors as members of a group.
The function causes the newly created actors to call <code>join</code><code>(...)</code> immediately and before <code>spawn_in_group</code> returns.
The usage of <code>spawn_in_group</code> is equal to <code>spawn</code>, except for an additional group argument.
The group handle is always the first argument, as shown in the examples below.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">fun1</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">fun2</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor1</span><span style="font-size:small"> : </span><span style="font-size:small">event_based_actor</span><span style="font-size:small"> { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">my_actor2</span><span style="font-size:small"> : </span><span style="font-size:small">event_based_actor</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">my_actor2</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/* ... */</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">grp</span><span style="font-size:small"> = </span><span style="font-size:small">group</span><span style="font-size:small">::</span><span style="font-size:small">get</span><span style="font-size:small">(...);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a1</span><span style="font-size:small"> = </span><span style="font-size:small">spawn_in_group</span><span style="font-size:small">(</span><span style="font-size:small">grp</span><span style="font-size:small">, </span><span style="font-size:small">fun1</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a2</span><span style="font-size:small"> = </span><span style="font-size:small">spawn_in_group</span><span style="font-size:small">(</span><span style="font-size:small">grp</span><span style="font-size:small">, </span><span style="font-size:small">fun2</span><span style="font-size:small">, 1, 2.0</span><span style="font-size:small">f</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a3</span><span style="font-size:small"> = </span><span style="font-size:small">spawn_in_group</span><span style="font-size:small"><</span><span style="font-size:small">my_actor1</span><span style="font-size:small">>(</span><span style="font-size:small">grp</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">a4</span><span style="font-size:small"> = </span><span style="font-size:small">spawn_in_group</span><span style="font-size:small"><</span><span style="font-size:small">my_actor2</span><span style="font-size:small">>(</span><span style="font-size:small">grp</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"hello my_actor2!"</span></span></span><span style="font-size:small">);</span></div>
<!--TOC section id="sec59" Managing Groups of Workers-->
<h2 id="sec59" class="section">14 Managing Groups of Workers</h2><!--SEC END --><p>
<a id="Sec::WorkerGroups"></a></p><p>When managing a set of workers, a central actor often dispatches requests to a set of workers.
For this purpose, the class <code>actor_pool</code> implements a lightweight abstraction for managing a set of workers using a dispatching policy.</p><p>Pools are created using the static member function <code>make</code>, which takes either one argument (the policy) or three (number of workers, factory function for workers, and dispatching policy).
After construction, one can add new workers via messages of the form (′<span style="font-style:italic">SYS</span>′, ′<span style="font-style:italic">PUT</span>′, <span style="font-style:italic">worker</span>), remove workers with (′<span style="font-style:italic">SYS</span>′, ′<span style="font-style:italic">DELETE</span>′, <span style="font-style:italic">worker</span>), and retrieve the set of workers as <code>vector</code><code><</code><code>actor</code><code>></code> via (′<span style="font-style:italic">SYS</span>′, ′<span style="font-style:italic">GET</span>′).
For example, adding <code>worker</code> to <code>my_pool</code> could be done using <code>send</code><code>(</code><code>my_pool</code><code>, </code><code>sys_atom</code><code>::</code><code>value</code><code>, </code><code>put_atom</code><code>::</code><code>value</code><code>, </code><code>worker</code><code>)</code>.</p><p>An actor pool takes ownership of its workers.
When forced to quit, it sends an exit messages to all of its workers, forcing them to quit as well.
The pool also monitors all of its workers.</p><p>Pools does not cache messages by default, but enqueue them directly in a workers mailbox. Consequently, a terminating worker loses all unprocessed messages.
For more advanced caching strategies, such as reliable message delivery, users can implement their own dispatching policies. </p>
<!--TOC subsection id="sec60" Predefined Dispatching Policies-->
<h3 id="sec60" class="subsection">14.1 Predefined Dispatching Policies</h3><!--SEC END --><p>The actor pool class comes with a set predefined policies for convenience.</p>
<!--TOC subsubsection id="sec61" <code>actor_pool</code><code>::</code><code>round_robin</code>-->
<h4 id="sec61" class="subsubsection">14.1.1 <code>actor_pool</code><code>::</code><code>round_robin</code></h4><!--SEC END --><p>This policy forwards incoming requests in a round-robin manner to workers.
There is no guarantee that messages are consumed, i.e., work items are lost if the worker exits before processing all of its messages.</p>
<!--TOC subsubsection id="sec62" <code>actor_pool</code><code>::</code><code>broadcast</code>-->
<h4 id="sec62" class="subsubsection">14.1.2 <code>actor_pool</code><code>::</code><code>broadcast</code></h4><!--SEC END --><p>This policy forwards <em>each</em> message to <em>all</em> workers.
Synchronous messages to the pool will be received by all workers, but the client will only recognize the first arriving response message—or error—and discard subsequent messages.
Note that this is not caused by the policy itself, but a consequence of forwarding synchronous messages to more than one actor.</p>
<!--TOC subsubsection id="sec63" <code>actor_pool</code><code>::</code><code>random</code>-->
<h4 id="sec63" class="subsubsection">14.1.3 <code>actor_pool</code><code>::</code><code>random</code></h4><!--SEC END --><p>This policy forwards incoming requests to one worker from the pool chosen uniformly at random.
Analogous to <code>round_robin</code>, this policy does not cache or redispatch messages.</p>
<!--TOC subsection id="sec64" Example-->
<h3 id="sec64" class="subsection">14.2 Example</h3><!--SEC END --><div class="lstlisting"><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">new_worker</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small">([]() -> </span><span style="font-size:small">behavior</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">x</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">y</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">x</span><span style="font-size:small"> + </span><span style="font-size:small">y</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">broadcast_example</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">scoped_actor</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawns a pool with 5 workers</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">pool5</span><span style="font-size:small"> = [] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">actor_pool</span><span style="font-size:small">::</span><span style="font-size:small">make</span><span style="font-size:small">(5, </span><span style="font-size:small">new_worker</span><span style="font-size:small">, </span><span style="font-size:small">actor_pool</span><span style="font-size:small">::</span><span style="font-size:small">broadcast</span><span style="font-size:small">{});</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawns a pool with 5 pools with 5 workers each</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">w</span><span style="font-size:small"> = </span><span style="font-size:small">actor_pool</span><span style="font-size:small">::</span><span style="font-size:small">make</span><span style="font-size:small">(5, </span><span style="font-size:small">pool5</span><span style="font-size:small">, </span><span style="font-size:small">actor_pool</span><span style="font-size:small">::</span><span style="font-size:small">broadcast</span><span style="font-size:small">{});</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// will be broadcasted to 25 workers</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">w</span><span style="font-size:small">, 1, 2);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">> </span><span style="font-size:small">results</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small"> = 0;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">receive_for</span><span style="font-size:small">(</span><span style="font-size:small">i</span><span style="font-size:small">, 25)(</span><span style="font-size:small">
</span><span style="font-size:small"> [&](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">res</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">push_back</span><span style="font-size:small">(</span><span style="font-size:small">res</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">size</span><span style="font-size:small">(), 25);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">all_of</span><span style="font-size:small">(</span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">begin</span><span style="font-size:small">(), </span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">end</span><span style="font-size:small">(),</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">res</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">res</span><span style="font-size:small"> == 3; }));</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// terminate pool(s) and all workers</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send_exit</span><span style="font-size:small">(</span><span style="font-size:small">w</span><span style="font-size:small">, </span><span style="font-size:small">exit_reason</span><span style="font-size:small">::</span><span style="font-size:small">user_shutdown</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec65" Platform-Independent Type System-->
<h2 id="sec65" class="section">15 Platform-Independent Type System</h2><!--SEC END --><p>
<a id="Sec::TypeSystem"></a></p><p>CAF provides a fully network transparent communication between actors.
Thus, CAF needs to serialize and deserialize messages.
Unfortunately, this is not possible using the RTTI system of C++.
CAF uses its own RTTI based on the class <code>uniform_type_info</code>, since it is not possible to extend <code>std</code><code>::</code><code><span style="color:blue">type_info</span></code>.</p><p>Unlike <code>std</code><code>::</code><code><span style="color:blue">type_info</span></code><code>::</code><code>name</code><code>()</code>, <code>uniform_type_info</code><code>::</code><code>name</code><code>()</code> is guaranteed to return the same name on all supported platforms. Furthermore, it allows to create an instance of a type by name.</p><div class="lstlisting"><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// creates a signed, 32 bit integer</span></span></span><span style="font-size:small">
</span><span style="font-size:small">uniform_value</span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small"> = </span><span style="font-size:small">uniform_typeid</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>()-></span><span style="font-size:small">create</span><span style="font-size:small">();</span></div><p>You should rarely, if ever, need to use <code>uniform_value</code> or <code>uniform_type_info</code>.
The type <code>uniform_value</code> stores a type-erased pointer along with the associated <code>uniform_type_info</code>.
The sole purpose of this simple abstraction is to enable the pattern matching engine of CAF to query the type information and then dispatch the value to a message handler.
When using a <code>message_builder</code>, each element is stored as a <code>uniform_value</code>.</p>
<!--TOC subsection id="sec66" User-Defined Data Types in Messages-->
<h3 id="sec66" class="subsection">15.1 User-Defined Data Types in Messages</h3><!--SEC END --><p>
<a id="Sec::TypeSystem::UserDefined"></a></p><p>All user-defined types must be explicitly “announced” so that CAF can (de)serialize them correctly, as shown in the example below.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"caf/all.hpp"</span></span></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">foo</span><span style="font-size:small"> { </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">; </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">; };</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">caf</span><span style="font-size:small">::</span><span style="font-size:small">announce</span><span style="font-size:small"><</span><span style="font-size:small">foo</span><span style="font-size:small">>(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"foo"</span></span></span><span style="font-size:small">, &</span><span style="font-size:small">foo</span><span style="font-size:small">::</span><span style="font-size:small">a</span><span style="font-size:small">, &</span><span style="font-size:small">foo</span><span style="font-size:small">::</span><span style="font-size:small">b</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... foo can now safely be used in messages ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small">}</span></div><p>Without announcing <code>foo</code>, CAF is not able to (de)serialize instances of it.
The function <code>announce</code><code>()</code> takes the class as template parameter.
The first argument to the function always is the type name followed by pointers to all members (or getter/setter pairs).
This works for all primitive data types and STL compliant containers.
See the announce examples 1 – 4 of the standard distribution for more details.</p><p>Obviously, there are limitations.
You have to implement serialize/deserialize by yourself if your class does implement an unsupported data structure.
See <code>announce_example_5</code><code>.</code><code>cpp</code> in the examples folder.
</p>
<!--TOC section id="sec67" Blocking API-->
<h2 id="sec67" class="section">16 Blocking API</h2><!--SEC END --><p>
<a id="Sec::BlockingAPI"></a></p><p>Besides event-based actors (the default implementation), CAF also provides context-switching and thread-mapped actors that can make use of the blocking API.
Those actor implementations are intended to ease migration of existing applications or to implement actors that need to have access to blocking receive primitives for other reasons.</p><p>Event-based actors differ in receiving messages from context-switching and thread-mapped actors: the former define their behavior as a message handler that is invoked whenever a new messages arrives in the actor’s mailbox (by using <code>become</code>), whereas the latter use an explicit, blocking receive function.</p>
<!--TOC subsection id="sec68" Receiving Messages-->
<h3 id="sec68" class="subsection">16.1 Receiving Messages</h3><!--SEC END --><p>The function <code>receive</code> sequentially iterates over all elements in the mailbox beginning with the first.
It takes a message handler that is applied to the elements in the mailbox until an element was matched by the handler.
An actor calling <code>receive</code> is blocked until it successfully dequeued a message from its mailbox or an optional timeout occurs.</p><div class="lstlisting"><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small">);</span></div><p>The code snippet above illustrates the use of <code>receive</code>.
Note that the message handler passed to <code>receive</code> is a temporary object at runtime.
Hence, using receive inside a loop would cause creation of a new handler on each iteration.
CAF provides three predefined receive loops to provide a more efficient but yet convenient way of defining receive loops.</p><table border=1 style="border-spacing:0;width:100%" class="cellpadding1"><tr><td style="vertical-align:top;text-align:left;border:solid 1px;" ><code><span style="color:#7F007F"><code>// DON'T</code></span></code></td><td style="vertical-align:top;text-align:left;border:solid 1px;" ><code><span style="color:#7F007F"><code>// DO</code></span></code> </td></tr>
<tr><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small"><span style="color:blue">for</span></span><span style="font-size:small"> (;;) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div></td><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small">receive_loop</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small">);</span></div></td></tr>
<tr><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">> </span><span style="font-size:small">results</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">for</span></span><span style="font-size:small"> (</span><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small"> = 0; </span><span style="font-size:small">i</span><span style="font-size:small"> < 10; ++</span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [&](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">value</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">push_back</span><span style="font-size:small">(</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div></td><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">vector</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">> </span><span style="font-size:small">results</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small"> = 0;</span><span style="font-size:small">
</span><span style="font-size:small">receive_for</span><span style="font-size:small">(</span><span style="font-size:small">i</span><span style="font-size:small">, 10) (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [&](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">value</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">results</span><span style="font-size:small">.</span><span style="font-size:small">push_back</span><span style="font-size:small">(</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div></td></tr>
<tr><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">received</span><span style="font-size:small"> = 0;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">do</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [&]() {</span><span style="font-size:small">
</span><span style="font-size:small"> ++</span><span style="font-size:small">received</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">} </span><span style="font-size:small"><span style="color:blue">while</span></span><span style="font-size:small"> (</span><span style="font-size:small">received</span><span style="font-size:small"> < 10);</span></div></td><td style="vertical-align:top;text-align:left;border:solid 1px;" ><div class="lstlisting"><span style="font-size:small"><span style="color:blue">size_t</span></span><span style="font-size:small"> </span><span style="font-size:small">received</span><span style="font-size:small"> = 0;</span><span style="font-size:small">
</span><span style="font-size:small">do_receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">others</span><span style="font-size:small"> >> [&]() {</span><span style="font-size:small">
</span><span style="font-size:small"> ++</span><span style="font-size:small">received</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">).</span><span style="font-size:small">until</span><span style="font-size:small">([&] { </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">received</span><span style="font-size:small"> >= 10; });</span></div></td></tr>
</table><p>The examples above illustrate the correct usage of the three loops <code>receive_loop</code>, <code>receive_for</code> and <code>do_receive</code><code>(...).</code><code>until</code>.
It is possible to nest receives and receive loops.</p><div class="lstlisting"><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">receive_loop</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>() >> [&](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">value1</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">receive</span><span style="font-size:small"> (</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">on</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">>() >> [&](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">value2</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">cout</span><span style="font-size:small"> << </span><span style="font-size:small">value1</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">" => "</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">value2</span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div>
<!--TOC subsection id="sec69" Receiving Synchronous Responses-->
<h3 id="sec69" class="subsection">16.2 Receiving Synchronous Responses</h3><!--SEC END --><p>Analogous to <code>sync_send</code><code>(...).</code><code>then</code><code>(...)</code> for event-based actors, blocking actors can use <code>sync_send</code><code>(...).</code><code>await</code><code>(...)</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">foo</span><span style="font-size:small">(</span><span style="font-size:small">blocking_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">actor</span><span style="font-size:small"> </span><span style="font-size:small">testee</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// testee replies with a string to 'get'</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">get_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">).</span><span style="font-size:small">await</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [&](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">string</span><span style="font-size:small">& </span><span style="font-size:small">str</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// handle str</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">after</span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">seconds</span><span style="font-size:small">(30)) >> [&]() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// handle error</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC subsection id="sec70" Mixing Actors and Threads with Scoped Actors-->
<h3 id="sec70" class="subsection">16.3 Mixing Actors and Threads with Scoped Actors</h3><!--SEC END --><p>The class <code>scoped_actor</code> offers a simple way of communicating with CAF actors from non-actor contexts.
It overloads <code><span style="color:blue">operator</span></code><code>-></code> to return a <code>blocking_actor</code><code>*</code>.
Hence, it behaves like the implicit <code>self</code> pointer in functor-based actors, only that it ceases to exist at scope end.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">test</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">scoped_actor</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// spawn some monitored actor</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">aut</span><span style="font-size:small"> = </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">monitored</span><span style="font-size:small">>(</span><span style="font-size:small">my_actor_impl</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">aut</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"hi there"</span></span></span><span style="font-size:small">).</span><span style="font-size:small">await</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> ... </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// handle response</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// self will be destroyed automatically here; any</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// actor monitoring it will receive down messages etc.</span></span></span><span style="font-size:small">
</span><span style="font-size:small">}</span></div><p>Note that <code>scoped_actor</code> throws an <code>actor_exited</code> exception when forced to quit for some reason, e.g., via an <code>exit_msg</code>.
Whenever a <code>scoped_actor</code> might end up receiving an <code>exit_msg</code> (because it links itself to another actor for example), the caller either needs to handle the exception or the actor needs to process <code>exit_msg</code> manually via <code>self</code><code>-></code><code>trap_exit</code><code>(</code><code><span style="color:blue">true</span></code><code>)</code>.
</p>
<!--TOC section id="sec71" Strongly Typed Actors-->
<h2 id="sec71" class="section">17 Strongly Typed Actors</h2><!--SEC END --><p>Strongly typed actors provide a convenient way of defining type-safe messaging interfaces.
Unlike untyped actorsd, typed actors are not allowed to use guard expressions.
When calling <code>become</code> in a strongly typed actor, <em>all</em> message handlers from the typed interface must be set.</p><p>Typed actors use handles of type <code>typed_actor</code><code><...></code> rather than <code>actor</code>, whereas the template parameters hold the messaging interface.
For example, an actor responding to two integers with a dobule would use the type <code>typed_actor</code><code><</code><code>replies_to</code><code><</code><code><span style="color:blue">int</span></code><code>, </code><code><span style="color:blue">int</span></code><code>>::</code><code>with</code><code><</code><code><span style="color:blue">double</span></code><code>>></code>.
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.</p>
<!--TOC subsection id="sec72" Spawning Typed Actors-->
<h3 id="sec72" class="subsection">17.1 Spawning Typed Actors</h3><!--SEC END --><p>
<a id="sec:strong:spawn"></a></p><p>Typed actors are spawned using the function <code>spawn_typed</code>.
The argument to this function call <em>must</em> be a match expression as shown in the example below, because the runtime of CAF needs to evaluate the signature of each message handler.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">p0</span><span style="font-size:small"> = </span><span style="font-size:small">spawn_typed</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">static_cast</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>(</span><span style="font-size:small">a</span><span style="font-size:small">) * </span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">make_tuple</span><span style="font-size:small">(</span><span style="font-size:small">a</span><span style="font-size:small"> * </span><span style="font-size:small">b</span><span style="font-size:small">, </span><span style="font-size:small">a</span><span style="font-size:small"> / </span><span style="font-size:small">b</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// assign to identical type</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">full_type</span><span style="font-size:small"> = </span><span style="font-size:small">typed_actor</span><span style="font-size:small"><</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"> >;</span><span style="font-size:small">
</span><span style="font-size:small">full_type</span><span style="font-size:small"> </span><span style="font-size:small">p1</span><span style="font-size:small"> = </span><span style="font-size:small">p0</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// assign to subtype</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">subtype1</span><span style="font-size:small"> = </span><span style="font-size:small">typed_actor</span><span style="font-size:small"><</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"> >;</span><span style="font-size:small">
</span><span style="font-size:small">subtype1</span><span style="font-size:small"> </span><span style="font-size:small">p2</span><span style="font-size:small"> = </span><span style="font-size:small">p0</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// assign to another subtype</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">subtype2</span><span style="font-size:small"> = </span><span style="font-size:small">typed_actor</span><span style="font-size:small"><</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">double</span></span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"> >;</span><span style="font-size:small">
</span><span style="font-size:small">subtype2</span><span style="font-size:small"> </span><span style="font-size:small">p3</span><span style="font-size:small"> = </span><span style="font-size:small">p0</span><span style="font-size:small">;</span></div>
<!--TOC subsection id="sec73" Class-based Typed Actors-->
<h3 id="sec73" class="subsection">17.2 Class-based Typed Actors</h3><!--SEC END --><p>Typed actors are spawned using the function <code>spawn_typed</code> and define their message passing interface as list of <code>replies_to</code><code><...>::</code><code>with</code><code><...></code> statements.
This interface is used in (1) <code>typed_event_based_actor</code><code><...></code>, which is the base class for typed actors, (2) the handle type <code>typed_actor</code><code><...></code>, and (3) <code>typed_behavior</code><code><...></code>, i.e., the behavior definition for typed actors.
Since this is rather redundant, the actor handle provides definitions for the behavior as well as the base class, as shown in the example below.
It is worth mentioning that all typed actors always use the event-based implementation, i.e., there is no typed actor implementation providing a blocking API.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">shutdown_request</span><span style="font-size:small"> { };</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">plus_request</span><span style="font-size:small"> { </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">; </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">; };</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">struct</span></span><span style="font-size:small"> </span><span style="font-size:small">minus_request</span><span style="font-size:small"> { </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">a</span><span style="font-size:small">; </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">b</span><span style="font-size:small">; };</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">typedef</span></span><span style="font-size:small"> </span><span style="font-size:small">typed_actor</span><span style="font-size:small"><</span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small">plus_request</span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small">minus_request</span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">>,</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">replies_to</span><span style="font-size:small"><</span><span style="font-size:small">shutdown_request</span><span style="font-size:small">>::</span><span style="font-size:small">with</span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small">>></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">calculator_type</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">calculator_type</span><span style="font-size:small">::</span><span style="font-size:small">behavior_type</span><span style="font-size:small">
</span><span style="font-size:small">typed_calculator</span><span style="font-size:small">(</span><span style="font-size:small">calculator_type</span><span style="font-size:small">::</span><span style="font-size:small">pointer</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">plus_request</span><span style="font-size:small">& </span><span style="font-size:small">pr</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">a</span><span style="font-size:small"> + </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">minus_request</span><span style="font-size:small">& </span><span style="font-size:small">pr</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">a</span><span style="font-size:small"> - </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">shutdown_request</span><span style="font-size:small">&) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">typed_calculator_class</span><span style="font-size:small"> : </span><span style="font-size:small"><span style="color:blue">public</span></span><span style="font-size:small"> </span><span style="font-size:small">calculator_type</span><span style="font-size:small">::</span><span style="font-size:small">base</span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">protected</span></span><span style="font-size:small">: </span><span style="font-size:small">behavior_type</span><span style="font-size:small"> </span><span style="font-size:small">make_behavior</span><span style="font-size:small">() </span><span style="font-size:small"><span style="color:blue">override</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> {</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">plus_request</span><span style="font-size:small">& </span><span style="font-size:small">pr</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">a</span><span style="font-size:small"> + </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">minus_request</span><span style="font-size:small">& </span><span style="font-size:small">pr</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">a</span><span style="font-size:small"> - </span><span style="font-size:small">pr</span><span style="font-size:small">.</span><span style="font-size:small">b</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">shutdown_request</span><span style="font-size:small">&) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">quit</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> };</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span></div><div class="lstlisting"><span style="font-size:small"><span style="color:blue">void</span></span><span style="font-size:small"> </span><span style="font-size:small">tester</span><span style="font-size:small">(</span><span style="font-size:small">event_based_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">const</span></span><span style="font-size:small"> </span><span style="font-size:small">calculator_type</span><span style="font-size:small">& </span><span style="font-size:small">testee</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">link_to</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// will be invoked if we receive an unexpected response message</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">on_sync_failure</span><span style="font-size:small">([=] {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"AUT (actor under test) failed"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">quit</span><span style="font-size:small">(</span><span style="font-size:small">exit_reason</span><span style="font-size:small">::</span><span style="font-size:small">user_shutdown</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// first test: 2 + 1 = 3</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">plus_request</span><span style="font-size:small">{2, 1}).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">r1</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">r1</span><span style="font-size:small"> == 3);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// second test: 2 - 1 = 1</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">sync_send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">minus_request</span><span style="font-size:small">{2, 1}).</span><span style="font-size:small">then</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [=](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">r2</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">r2</span><span style="font-size:small"> == 1);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// both tests succeeded</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"AUT (actor under test) "</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"seems to be ok"</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">send</span><span style="font-size:small">(</span><span style="font-size:small">testee</span><span style="font-size:small">, </span><span style="font-size:small">shutdown_request</span><span style="font-size:small">{});</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// announce custom message types</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">announce</span><span style="font-size:small"><</span><span style="font-size:small">shutdown_request</span><span style="font-size:small">>(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"shutdown_request"</span></span></span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">announce</span><span style="font-size:small"><</span><span style="font-size:small">plus_request</span><span style="font-size:small">>(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"plus_request"</span></span></span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> &</span><span style="font-size:small">plus_request</span><span style="font-size:small">::</span><span style="font-size:small">a</span><span style="font-size:small">, &</span><span style="font-size:small">plus_request</span><span style="font-size:small">::</span><span style="font-size:small">b</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">announce</span><span style="font-size:small"><</span><span style="font-size:small">minus_request</span><span style="font-size:small">>(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"minus_request"</span></span></span><span style="font-size:small">,</span><span style="font-size:small">
</span><span style="font-size:small"> &</span><span style="font-size:small">minus_request</span><span style="font-size:small">::</span><span style="font-size:small">a</span><span style="font-size:small">, &</span><span style="font-size:small">minus_request</span><span style="font-size:small">::</span><span style="font-size:small">b</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// test function-based impl</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">tester</span><span style="font-size:small">, </span><span style="font-size:small">spawn_typed</span><span style="font-size:small">(</span><span style="font-size:small">typed_calculator</span><span style="font-size:small">));</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// test class-based impl</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small">(</span><span style="font-size:small">tester</span><span style="font-size:small">, </span><span style="font-size:small">spawn_typed</span><span style="font-size:small"><</span><span style="font-size:small">typed_calculator_class</span><span style="font-size:small">>());</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// done</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">shutdown</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> 0;</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC section id="sec74" Messages-->
<h2 id="sec74" class="section">18 Messages</h2><!--SEC END --><p>Messages in CAF are type-erased, copy-on-write tuples.
The actual message type itself is usually hidden, as actors use pattern matching to decompose messages automatically.
However, the classes <code>message</code> and <code>message_builder</code> allow more advanced usage scenarios than only sending data from one actor to another.</p>
<!--TOC subsection id="sec75" Class <span style="font-family:monospace">message</span>-->
<h3 id="sec75" class="subsection">18.1 Class <span style="font-family:monospace">message</span></h3><!--SEC END --><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="vertical-align:middle;text-align:left;" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member functions</span></span><span style="font-size:small"> </span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Observers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">empty</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns whether this message is empty </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">size</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the size of this message </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small">* </span></code><code><span style="font-size:small">at</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns a const pointer to the element at position </span><code><span style="font-size:small">p</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">get_as</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns a const ref. to the element at position </span><code><span style="font-size:small">p</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">match_element</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns whether the element at position </span><code><span style="font-size:small">p</span></code><span style="font-size:small"> has type </span><code><span style="font-size:small">T</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small">... </span></code><code><span style="font-size:small">Ts</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">match_elements</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns whether this message has the types </span><code><span style="font-size:small">Ts</span></code><code><span style="font-size:small">...</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">drop</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message with all but the first </span><code><span style="font-size:small">n</span></code><span style="font-size:small"> values </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">drop_right</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message with all but the last </span><code><span style="font-size:small">n</span></code><span style="font-size:small"> values </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">take</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message from the first </span><code><span style="font-size:small">n</span></code><span style="font-size:small"> values </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">take_right</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message from the last </span><code><span style="font-size:small">n</span></code><span style="font-size:small"> values </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">slice</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message from </span><code><span style="font-size:small">[</span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small"> + </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">slice</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates a new message from </span><code><span style="font-size:small">[</span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small"> + </span></code><code><span style="font-size:small">n</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">extract</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">message_handler</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">See </span><a href="#Sec%3A%3AMessages%3A%3AExtract"><span style="font-size:small">18.3</span></a><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">extract_opts</span></code><code><span style="font-size:small">(...)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">See </span><a href="#Sec%3A%3AMessages%3A%3AExtractOpts"><span style="font-size:small">18.4</span></a><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Modifiers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">optional</span></code><code><span style="font-size:small"><</span></code><code><span style="font-size:small">message</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">apply</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">message_handler</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">f</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns </span><code><span style="font-size:small">f</span></code><code><span style="font-size:small">(*</span></code><code><span style="font-size:small"><span style="color:blue">this</span></span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">void</span></span></code><code><span style="font-size:small">* </span></code><code><span style="font-size:small">mutable_at</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns a pointer to the element at position p </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">get_as_mutable</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">p</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns a reference to the element at position p </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
</table>
<!--TOC subsection id="sec76" Class <span style="font-family:monospace">message_builder</span>-->
<h3 id="sec76" class="subsection">18.2 Class <span style="font-family:monospace">message_builder</span></h3><!--SEC END --><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="vertical-align:middle;text-align:left;" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member functions</span></span><span style="font-size:small"> </span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Constructors</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Creates an empty message builder </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">(</span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">first</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">last</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Adds all elements from range </span><code><span style="font-size:small">[</span></code><code><span style="font-size:small">first</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">last</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Observers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">empty</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns whether this message is empty </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">size_t</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">size</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns the size of this message </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">to_message</span></code><code><span style="font-size:small">( )</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Converts the buffer to an actual message object </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">append</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">val</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Adds </span><code><span style="font-size:small">val</span></code><span style="font-size:small"> to the buffer </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">template</span></span></code><code><span style="font-size:small"> <</span></code><code><span style="font-size:small"><span style="color:blue">class</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">append</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">first</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">Iter</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">last</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Adds all elements from range </span><code><span style="font-size:small">[</span></code><code><span style="font-size:small">first</span></code><code><span style="font-size:small">, </span></code><code><span style="font-size:small">last</span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">extract</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">message_handler</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">See </span><a href="#Sec%3A%3AMessages%3A%3AExtract"><span style="font-size:small">18.3</span></a><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">extract_opts</span></code><code><span style="font-size:small">(...)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">See </span><a href="#Sec%3A%3AMessages%3A%3AExtractOpts"><span style="font-size:small">18.4</span></a><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Modifiers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">optional</span></code><code><span style="font-size:small"><</span></code><code><span style="font-size:small">message</span></code><code><span style="font-size:small">></span></code><span style="font-size:small"> </span><code><span style="font-size:small">apply</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">message_handler</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">f</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns </span><code><span style="font-size:small">f</span></code><code><span style="font-size:small">(*</span></code><code><span style="font-size:small"><span style="color:blue">this</span></span></code><code><span style="font-size:small">)</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">message</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">move_to_message</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Transfers ownership of its data to the new message </span><span style="font-size:small"><span style="font-weight:bold">Warning</span></span><span style="font-size:small">: this function leaves the builder in an </span><span style="font-size:small"><em>invalid state</em></span><span style="font-size:small">, i.e., calling any member function on it afterwards is undefined behavior </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
</table>
<!--TOC subsection id="sec77" Extracting-->
<h3 id="sec77" class="subsection">18.3 Extracting</h3><!--SEC END --><p>
<a id="Sec::Messages::Extract"></a></p><p>The member function <code>message</code><code>::</code><code>extract</code> removes matched elements from a message. x
Messages are filtered by repeatedly applying a message handler to the greatest remaining slice, whereas slices are generated in the sequence <code>[0, </code><code>size</code><code>)</code>, <code>[0, </code><code>size</code><code>-1)</code>, <code>...</code>, <code>[1, </code><code>size</code><code>-1)</code>, <code>...</code>, <code>[</code><code>size</code><code>-1, </code><code>size</code><code>)</code>.
Whenever a slice is matched, it is removed from the message and the next slice starts at the same index on the reduced message.</p><p>For example:</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">msg</span><span style="font-size:small"> = </span><span style="font-size:small">make_message</span><span style="font-size:small">(1, 2.</span><span style="font-size:small">f</span><span style="font-size:small">, 3.</span><span style="font-size:small">f</span><span style="font-size:small">, 4);</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// remove float and integer pairs</span></span></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">msg2</span><span style="font-size:small"> = </span><span style="font-size:small">msg</span><span style="font-size:small">.</span><span style="font-size:small">extract</span><span style="font-size:small">({</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small">) { },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small">) { }</span><span style="font-size:small">
</span><span style="font-size:small">});</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">assert</span></span><span style="font-size:small">(</span><span style="font-size:small">msg2</span><span style="font-size:small"> == </span><span style="font-size:small">make_message</span><span style="font-size:small">(1, 4));</span></div><p>Step-by-step explanation:</p><ul class="itemize"><li class="li-itemize">
Slice 1: <code>(1, 2.</code><code>f</code><code>, 3.</code><code>f</code><code>, 4)</code>, no match
</li><li class="li-itemize">Slice 2: <code>(1, 2.</code><code>f</code><code>, 3.</code><code>f</code><code>)</code>, no match
</li><li class="li-itemize">Slice 3: <code>(1, 2.</code><code>f</code><code>)</code>, no match
</li><li class="li-itemize">Slice 4: <code>(1)</code>, no match
</li><li class="li-itemize">Slice 5: <code>(2.</code><code>f</code><code>, 3.</code><code>f</code><code>, 4)</code>, no match
</li><li class="li-itemize">Slice 6: <code>(2.</code><code>f</code><code>, 3.</code><code>f</code><code>)</code>, <em>match</em>; new message is <code>(1, 4)</code>
</li><li class="li-itemize">Slice 7: <code>(4)</code>, no match
</li></ul><p>Slice 7 is <code>(4)</code>, i.e., does not contain the first element, because the match on slice 6 occurred at index position 1. The function <code>extract</code> iterates a message only once, from left to right.
The returned message contains the remaining, i.e., unmatched, elements.</p>
<!--TOC subsection id="sec78" Extracting Command Line Options-->
<h3 id="sec78" class="subsection">18.4 Extracting Command Line Options</h3><!--SEC END --><p>
<a id="Sec::Messages::ExtractOpts"></a></p><p>The class <code>message</code> also contains a convenience interface to <code>extract</code> for parsing command line options: the member function <code>extract_opts</code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">argc</span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:blue">char</span></span><span style="font-size:small">** </span><span style="font-size:small">argv</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">uint16_t</span><span style="font-size:small"> </span><span style="font-size:small">port</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">string</span><span style="font-size:small"> </span><span style="font-size:small">host</span><span style="font-size:small"> = </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"localhost"</span></span></span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">auto</span></span><span style="font-size:small"> </span><span style="font-size:small">res</span><span style="font-size:small"> = </span><span style="font-size:small">message_builder</span><span style="font-size:small">(</span><span style="font-size:small">argv</span><span style="font-size:small"> + 1, </span><span style="font-size:small">argv</span><span style="font-size:small"> + </span><span style="font-size:small">argc</span><span style="font-size:small">).</span><span style="font-size:small">extract_opts</span><span style="font-size:small">({</span><span style="font-size:small">
</span><span style="font-size:small"> {</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"port,p"</span></span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"set port"</span></span></span><span style="font-size:small">, </span><span style="font-size:small">port</span><span style="font-size:small">},</span><span style="font-size:small">
</span><span style="font-size:small"> {</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"host,H"</span></span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"set host (default: localhost)"</span></span></span><span style="font-size:small">, </span><span style="font-size:small">host</span><span style="font-size:small">},</span><span style="font-size:small">
</span><span style="font-size:small"> {</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"verbose,v"</span></span></span><span style="font-size:small">, </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"enable verbose mode"</span></span></span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">res</span><span style="font-size:small">.</span><span style="font-size:small">opts</span><span style="font-size:small">.</span><span style="font-size:small">count</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"help"</span></span></span><span style="font-size:small">) > 0) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// CLI arguments contained "-h", "--help", or "-?" (builtin);</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// note: the help text has already been printed to stdout</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">return</span></span><span style="font-size:small"> 0;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (!</span><span style="font-size:small">res</span><span style="font-size:small">.</span><span style="font-size:small">remainder</span><span style="font-size:small">.</span><span style="font-size:small">empty</span><span style="font-size:small">()) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... extract did not consume all CLI options ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">if</span></span><span style="font-size:small"> (</span><span style="font-size:small">res</span><span style="font-size:small">.</span><span style="font-size:small">opts</span><span style="font-size:small">.</span><span style="font-size:small">count</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"verbose"</span></span></span><span style="font-size:small">) > 0) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ... enable verbose mode ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// ...</span></span></span><span style="font-size:small">
</span><span style="font-size:small">}</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*</span><span style="font-size:small">
</span><span style="font-size:small">Output of ./program_name -h:</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">Allowed options:</span><span style="font-size:small">
</span><span style="font-size:small"> -p [--port] arg : set port</span><span style="font-size:small">
</span><span style="font-size:small"> -H [--host] arg : set host (default: localhost)</span><span style="font-size:small">
</span><span style="font-size:small"> -v [--verbose] : enable verbose mode</span><span style="font-size:small">
</span><span style="font-size:small">*/</span></span></span></div>
<!--TOC section id="sec79" Common Pitfalls-->
<h2 id="sec79" class="section">19 Common Pitfalls</h2><!--SEC END --><p>
<a id="Sec::Pitfalls"></a></p>
<!--TOC subsection id="sec80" Defining Patterns-->
<h3 id="sec80" class="subsection">19.1 Defining Patterns</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
C++ evaluates comma-separated expressions from left-to-right, using only the last element as return type of the whole expression. This means that message handlers and behaviors must <em>not</em> be initialized like this:
<div class="lstlisting"><span style="font-size:small">message_handler</span><span style="font-size:small"> </span><span style="font-size:small">wrong</span><span style="font-size:small"> = (</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div>The correct way to initialize message handlers and behaviors is to either use the constructor or the member function <code>assign</code>:
<div class="lstlisting"><span style="font-size:small">message_handler</span><span style="font-size:small"> </span><span style="font-size:small">ok1</span><span style="font-size:small">{</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">};</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small">message_handler</span><span style="font-size:small"> </span><span style="font-size:small">ok2</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// some place later</span></span></span><span style="font-size:small">
</span><span style="font-size:small">ok2</span><span style="font-size:small">.</span><span style="font-size:small">assign</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> },</span><span style="font-size:small">
</span><span style="font-size:small"> [](</span><span style="font-size:small"><span style="color:blue">float</span></span><span style="font-size:small"> </span><span style="font-size:small">f</span><span style="font-size:small">) { </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">/*...*/</span></span></span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small">);</span></div></li></ul>
<!--TOC subsection id="sec81" Event-Based API-->
<h3 id="sec81" class="subsection">19.2 Event-Based API</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
The functions <code>become</code> and <code>handle_response</code> do not block, i.e., always return immediately.
Thus, one should <span style="font-style:italic">always</span> capture by value in lambda expressions, because all references on the stack will cause undefined behavior if the lambda expression is executed.
</li></ul>
<!--TOC subsection id="sec82" Synchronous Messages-->
<h3 id="sec82" class="subsection">19.3 Synchronous Messages</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">A handle returned by <code>sync_send</code> represents <em>exactly one</em> response message.
Therefore, it is not possible to receive more than one response message.</li><li class="li-itemize">The handle returned by <code>sync_send</code> is bound to the calling actor.
It is not possible to transfer a handle to a response to another actor.</li></ul>
<!--TOC subsection id="sec83" Sharing-->
<h3 id="sec83" class="subsection">19.4 Sharing</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
It is strongly recommended to <span style="font-weight:bold">not</span> share states between actors.
In particular, no actor shall ever access member variables or member functions of another actor.
Accessing shared memory segments concurrently can cause undefined behavior that is incredibly hard to find and debug.
However, sharing <span style="font-style:italic">data</span> between actors is fine, as long as the data is <span style="font-style:italic">immutable</span> and its lifetime is guaranteed to outlive all actors.
The simplest way to meet the lifetime guarantee is by storing the data in smart pointers such as <code>std</code><code>::</code><code>shared_ptr</code>.
Nevertheless, the recommended way of sharing informations is message passing.
Sending the same message to multiple actors does not result in copying the data several times.
</li></ul>
<!--TOC subsection id="sec84" Constructors of Class-based Actors-->
<h3 id="sec84" class="subsection">19.5 Constructors of Class-based Actors</h3><!--SEC END --><ul class="itemize"><li class="li-itemize">
You should <span style="font-weight:bold">not</span> try to send or receive messages in a constructor or destructor, because the actor is not fully initialized at this point.
</li></ul>
<!--TOC section id="sec85" Appendix-->
<h2 id="sec85" class="section">20 Appendix</h2><!--SEC END -->
<!--TOC subsection id="sec86" Class <span style="font-family:monospace">option</span>-->
<h3 id="sec86" class="subsection">20.1 Class <span style="font-family:monospace">option</span></h3><!--SEC END --><p>
<a id="Appendix::Option"></a></p><p>Defined in header <code><span style="color:#007F00"><code>"caf/option.hpp"</code></span></code>.</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">template</span></span><span style="font-size:small"><</span><span style="font-size:small"><span style="color:blue">typename</span></span><span style="font-size:small"> </span><span style="font-size:small">T</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">class</span></span><span style="font-size:small"> </span><span style="font-size:small">option</span><span style="font-size:small">;</span></div><p>Represents an optional value.</p><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member types</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><span style="font-size:small"><span style="font-weight:bold">Member type</span></span></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"><span style="font-weight:bold">Definition</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">type</span></code></td><td style="vertical-align:middle;text-align:left;" ><code><span style="font-size:small">T</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:large"><span style="font-weight:bold">Member Functions</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Constructs an empty option </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">value</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Initializes </span><code><span style="font-size:small"><span style="color:blue">this</span></span></code><span style="font-size:small"> with </span><code><span style="font-size:small">value</span></code><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">option</span></code><code><span style="font-size:small">&)</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small">option</span></code><code><span style="font-size:small">&&)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Copy/move construction </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small">=(</span></code><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">option</span></code><code><span style="font-size:small">&)</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small">option</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small">=(</span></code><code><span style="font-size:small">option</span></code><code><span style="font-size:small">&&)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Copy/move assignment </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Observers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">valid</span></code><code><span style="font-size:small">()</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small"><span style="color:blue">explicit</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small">()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns </span><code><span style="font-size:small"><span style="color:blue">true</span></span></code><span style="font-size:small"> if </span><code><span style="font-size:small"><span style="color:blue">this</span></span></code><span style="font-size:small"> has a value </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">empty</span></code><code><span style="font-size:small">()</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small"><span style="color:blue">bool</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small">!()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns </span><code><span style="font-size:small"><span style="color:blue">true</span></span></code><span style="font-size:small"> if </span><code><span style="font-size:small"><span style="color:blue">this</span></span></code><span style="font-size:small"> does </span><span style="font-size:small"><span style="font-weight:bold">not</span></span><span style="font-size:small"> has a value </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">get</span></code><code><span style="font-size:small">()</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small">*()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Access stored value </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">get_or_else</span></code><code><span style="font-size:small">(</span></code><code><span style="font-size:small"><span style="color:blue">const</span></span></code><code><span style="font-size:small"> </span></code><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">x</span></code><code><span style="font-size:small">)</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Returns </span><code><span style="font-size:small">get</span></code><code><span style="font-size:small">()</span></code><span style="font-size:small"> if valid, </span><code><span style="font-size:small">x</span></code><span style="font-size:small"> otherwise </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span></td></tr>
<tr><td style="text-align:left;white-space:nowrap" colspan=2><span style="font-size:small"><span style="font-weight:bold">Modifiers</span></span><span style="font-size:small"> </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small"> </span><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small">get</span></code><code><span style="font-size:small">()</span></code><span style="font-size:small"><br>
</span><code><span style="font-size:small">T</span></code><code><span style="font-size:small">& </span></code><code><span style="font-size:small"><span style="color:blue">operator</span></span></code><code><span style="font-size:small">*()</span></code></td><td style="vertical-align:middle;text-align:left;" ><span style="font-size:small">Access stored value </span></td></tr>
<tr><td class="hbar" colspan=2><span style="font-size:small"></span></td></tr>
</table>
<!--TOC subsection id="sec87" Using <span style="font-family:monospace">aout</span> – A Concurrency-safe Wrapper for <span style="font-family:monospace">cout</span>-->
<h3 id="sec87" class="subsection">20.2 Using <span style="font-family:monospace">aout</span> – A Concurrency-safe Wrapper for <span style="font-family:monospace">cout</span></h3><!--SEC END --><p>When using <code>cout</code> from multiple actors, output often appears interleaved.
Moreover, using <code>cout</code> from multiple actors – and thus from multiple threads – in parallel should be avoided regardless, since the standard does not guarantee a thread-safe implementation.</p><p>By replacing <span style="font-family:monospace">std::cout</span> with <span style="font-family:monospace">caf::aout</span>, actors can achieve a concurrency-safe text output.
The header <code>caf</code><code>/</code><code>all</code><code>.</code><code>hpp</code> also defines overloads for <span style="font-family:monospace">std::endl</span> and <span style="font-family:monospace">std::flush</span> for <code>aout</code>, but does not support the full range of ostream operations (yet).
Each write operation to <span style="font-family:monospace">aout</span> sends a message to a ‘hidden’ actor (keep in mind, sending messages from actor constructors is not safe).
This actor only prints lines, unless output is forced using <code>flush</code>.
The example below illustrates printing of lines of text from multiple actors (in random order).</p><div class="lstlisting"><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> <</span><span style="font-size:small">chrono</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> <</span><span style="font-size:small">cstdlib</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> <</span><span style="font-size:small">iostream</span><span style="font-size:small">></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">#include</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"caf/all.hpp"</span></span></span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">namespace</span></span><span style="font-size:small"> </span><span style="font-size:small">caf</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">using</span></span><span style="font-size:small"> </span><span style="font-size:small">done_atom</span><span style="font-size:small"> = </span><span style="font-size:small">atom_constant</span><span style="font-size:small"><</span><span style="font-size:small">atom</span><span style="font-size:small">(</span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"done"</span></span></span><span style="font-size:small">)>;</span><span style="font-size:small">
</span><span style="font-size:small">
</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">main</span><span style="font-size:small">() {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">srand</span><span style="font-size:small">(</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">time</span><span style="font-size:small">(0));</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:blue">for</span></span><span style="font-size:small"> (</span><span style="font-size:small"><span style="color:blue">int</span></span><span style="font-size:small"> </span><span style="font-size:small">i</span><span style="font-size:small"> = 1; </span><span style="font-size:small">i</span><span style="font-size:small"> <= 50; ++</span><span style="font-size:small">i</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">spawn</span><span style="font-size:small"><</span><span style="font-size:small">blocking_api</span><span style="font-size:small">>([</span><span style="font-size:small">i</span><span style="font-size:small">](</span><span style="font-size:small">blocking_actor</span><span style="font-size:small">* </span><span style="font-size:small">self</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"Hi there! This is actor nr. "</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> << </span><span style="font-size:small">i</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"!"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">chrono</span><span style="font-size:small">::</span><span style="font-size:small">milliseconds</span><span style="font-size:small"> </span><span style="font-size:small">tout</span><span style="font-size:small">{</span><span style="font-size:small">std</span><span style="font-size:small">::</span><span style="font-size:small">rand</span><span style="font-size:small">() % 1000};</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">delayed_send</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">, </span><span style="font-size:small">tout</span><span style="font-size:small">, </span><span style="font-size:small">done_atom</span><span style="font-size:small">::</span><span style="font-size:small">value</span><span style="font-size:small">);</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">self</span><span style="font-size:small">-></span><span style="font-size:small">receive</span><span style="font-size:small">(</span><span style="font-size:small">
</span><span style="font-size:small"> [</span><span style="font-size:small">i</span><span style="font-size:small">, </span><span style="font-size:small">self</span><span style="font-size:small">](</span><span style="font-size:small">done_atom</span><span style="font-size:small">) {</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">aout</span><span style="font-size:small">(</span><span style="font-size:small">self</span><span style="font-size:small">) << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">"Actor nr. "</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> << </span><span style="font-size:small">i</span><span style="font-size:small"> << </span><span style="font-size:small"><span style="color:#007F00"><span style="font-size:small">" says goodbye!"</span></span></span><span style="font-size:small"> << </span><span style="font-size:small">endl</span><span style="font-size:small">;</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> );</span><span style="font-size:small">
</span><span style="font-size:small"> });</span><span style="font-size:small">
</span><span style="font-size:small"> }</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small"><span style="color:#7F007F"><span style="font-size:small">// wait until all other actors we've spawned are done</span></span></span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">await_all_actors_done</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small"> </span><span style="font-size:small">shutdown</span><span style="font-size:small">();</span><span style="font-size:small">
</span><span style="font-size:small">}</span></div>
<!--TOC subsection id="sec88" Migration Guides-->
<h3 id="sec88" class="subsection">20.3 Migration Guides</h3><!--SEC END --><p>The guides in this section document all possibly breaking changes in the library for that last versions of CAF.</p>
<!--TOC subsubsection id="sec89" 0.8 ⇒ 0.9-->
<h4 id="sec89" class="subsubsection">20.3.1 0.8 ⇒ 0.9</h4><!--SEC END --><p>Version 0.9 included a lot of changes and improvements in its implementation, but it also made breaking changes to the API.</p>
<!--TOC paragraph id="sec90" <code>self</code> has been removed-->
<h4 id="sec90" class="paragraph"><code>self</code> has been removed</h4><!--SEC END --><p> </p><p>This is the biggest library change since the initial release.
The major problem with this keyword-like identifier is that it must have a single type as it’s implemented as a thread-local variable.
Since there are so many different kinds of actors (event-based or blocking, untyped or typed), <code>self</code> needs to perform type erasure at some point, rendering it ultimately useless.
Instead of a thread-local pointer, you can now use the first argument in functor-based actors to "catch" the self pointer with proper type information.</p>
<!--TOC paragraph id="sec91" <code>actor_ptr</code> has been replaced-->
<h4 id="sec91" class="paragraph"><code>actor_ptr</code> has been replaced</h4><!--SEC END --><p> </p><p>CAF now distinguishes between handles to actors, i.e., <code>typed_actor</code><code><...></code> or simply <code>actor</code>, and <em>addresses</em> of actors, i.e., <code>actor_addr</code>. The reason for this change is that each actor has a logical, (network-wide) unique address, which is used by the networking layer of CAF. Furthermore, for monitoring or linking, the address is all you need. However, the address is not sufficient for sending messages, because it doesn’t have any type information. The function <code>last_sender</code><code>()</code> now returns the <em>address</em> of the sender.
This means that previously valid code such as <code>send</code><code>(</code><code>last_sender</code><code>(), ...)</code> will cause a compiler error.
However, the recommended way of replying to messages is to return the result from the message handler.</p>
<!--TOC paragraph id="sec92" The API for typed actors is now similar to the API for untyped actors-->
<h4 id="sec92" class="paragraph">The API for typed actors is now similar to the API for untyped actors</h4><!--SEC END --><p> </p><p>The APIs of typed and untyped actors have been harmonized.
Typed actors can now be published in the network and also use all operations untyped actors can.</p>
<!--TOC subsubsection id="sec93" 0.9 ⇒ 0.10 (<span style="font-family:monospace">libcppa</span> ⇒ CAF)-->
<h4 id="sec93" class="subsubsection">20.3.2 0.9 ⇒ 0.10 (<span style="font-family:monospace">libcppa</span> ⇒ CAF)</h4><!--SEC END --><p>The first release under the new name CAF is an overhaul of the entire library.
Some classes have been renamed or relocated, others have been removed.
The purpose of this refactoring was to make the library easier to grasp and to make its API more consistent.
All classes now live in the namespace <code>caf</code> and all headers have the top level folder “caf” instead of “cppa”.
For example, <code>#</code><code>include</code><code> </code><code><span style="color:#007F00"><code>"cppa/actor.hpp"</code></span></code> becomes <code>#</code><code>include</code><code> </code><code><span style="color:#007F00"><code>"caf/actor.hpp"</code></span></code>.
Further, the convenience header to get all parts of the user API is now <code><span style="color:#007F00"><code>"caf/all.hpp"</code></span></code>.
The networking has been separated from the core library.
To get the networking components, simply include <code><span style="color:#007F00"><code>"caf/io/all.hpp"</code></span></code> and use the namespace <code>caf</code><code>::</code><code>io</code>, e.g., <code>caf</code><code>::</code><code>io</code><code>::</code><code>remote_actor</code>.</p><p>Version 0.10 still includes the header <code>cppa</code><code>/</code><code>cppa</code><code>.</code><code>hpp</code> to make the transition process for users easier and to not break existing code right away.
The header defines the namespace <code>cppa</code> as an alias for <code>caf</code>.
Furthermore, it provides implementations or type aliases for renamed or removed classes such as <code>cow_tuple</code>.
You won’t get any warning about deprecated headers with 0.10.
However, we will add this warnings in the next library version and remove deprecated code eventually.</p><p>Even when using the backwards compatibility header, the new library has breaking changes.
For instance, guard expressions have been removed entirely.
The reasoning behind this decision is that we already have projections to modify the outcome of a match.
Guard expressions add little expressive power to the library but a whole lot of code that is hard to maintain in the long run due to its complexity.
Using projections to not only perform type conversions but also to restrict values is the more natural choice.</p><p>The following table summarizes the changes made to the API.</p><table style="border-spacing:6px;border-collapse:separate;width:100%" class="cellpading0"><tr><td style="vertical-align:middle;text-align:left;" > Change</td><td style="vertical-align:middle;text-align:left;" >Explanation </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>any_tuple</code><code> => </code><code>message</code></td><td style="vertical-align:middle;text-align:left;" >This type is only being used to pass a message from one actor to another. Hence, <code>message</code> is the logical name. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>partial_function</code><code> => </code> <code>message_handler</code></td><td style="vertical-align:middle;text-align:left;" >Technically, it still is a partial function, but wanted to emphasize its use case in the library. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>cow_tuple</code><code> => </code><code>X</code></td><td style="vertical-align:middle;text-align:left;" >We want to provide a streamlined, simple API. Shipping a full tuple abstraction with the library does not fit into this philosophy. The removal of <code>cow_tuple</code> implies the removal of related functions such as <code>tuple_cast</code>. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>cow_ptr</code><code> => </code><code>X</code></td><td style="vertical-align:middle;text-align:left;" >This pointer class is an implementation detail of <code>message</code> and should not live in the global namespace in the first place. It also had the wrong name, because it is intrusive. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>X</code><code> => </code><code>message_builder</code></td><td style="vertical-align:middle;text-align:left;" >This new class can be used to create messages dynamically. For example, the content of a vector can be used to create a message using a series of <code>append</code> calls. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
<tr><td style="vertical-align:middle;text-align:left;" > <code>accept_handle</code>, <code>connection_handle</code>, <code>publish</code>, <code>remote_actor</code>, <code>max_msg_size</code>, <code>typed_publish</code>, <code>typed_remote_actor</code>, <code>publish_local_groups</code>, <code>new_connection_msg</code>, <code>new_data_msg</code>, <code>connection_closed_msg</code>, <code>acceptor_closed_msg</code></td><td style="vertical-align:middle;text-align:left;" >These classes concern I/O functionality and have thus been moved to <code>caf</code><code>::</code><code>io</code>. </td></tr>
<tr><td class="hbar" colspan=2></td></tr>
</table>
<!--TOC subsubsection id="sec94" 0.10 ⇒ 0.11-->
<h4 id="sec94" class="subsubsection">20.3.3 0.10 ⇒ 0.11</h4><!--SEC END --><p>Version 0.11 introduced new, optional components.
The core library itself, however, mainly received optimizations and bugfixes with one exception: the member function <code>on_exit</code> is no longer virtual.
You can still provide it to define a custom exit handler, but you must not use <code><span style="color:blue">override</span></code>.</p>
<!--TOC subsubsection id="sec95" 0.11 ⇒ 0.12-->
<h4 id="sec95" class="subsubsection">20.3.4 0.11 ⇒ 0.12</h4><!--SEC END --><p>Version 0.12 removed two features:</p><ul class="itemize"><li class="li-itemize">
Type names are no longer demangled automatically.
Hence, users must explicitly pass the type name as first argument when using <code>announce</code>, i.e., <code>announce</code><code><</code><code>my_class</code><code>>(...)</code> becomes <code>announce</code><code><</code><code>my_class</code><code>>(</code><code><span style="color:#007F00"><code>"my_class"</code></span></code><code>, ...)</code>.</li><li class="li-itemize">Synchronous send blocks no longer support <code>continue_with</code>.
This feature has been removed without substitution.
</li></ul>
<!--TOC subsubsection id="sec96" 0.12 ⇒ 0.13-->
<h4 id="sec96" class="subsubsection">20.3.5 0.12 ⇒ 0.13</h4><!--SEC END --><p>This release removes the (since 0.9 deprecated) <code>cppa</code> headers and deprecates all <code>*</code><code>_send_tuple</code> versions (simply use the function without <code>_tuple</code> suffix).</p><p>In case you were using the old <code>cppa</code><code>::</code><code>options_description</code> API, you can migrate to the new API based on <code>extract</code> (cf. <a href="#Sec%3A%3AMessages%3A%3AExtractOpts">18.4</a>).</p><p>Most importantly, version 0.13 slightly changes <code>last_dequeued</code> and <code>last_sender</code>.
Both functions will now cause undefined behavior (dereferencing a <code><span style="color:blue">nullptr</span></code>) instead of returning dummy values when accessed from outside a callback or after forwarding the current message.
Besides, these function names were not a good choice in the first place, since “last” implies accessing data received in the past.
As a result, both functions are now deprecated.
Their replacements are named <code>current_message</code> and <code>current_sender</code> (cf. Section <a href="#Sec%3A%3AActors%3A%3AInterfaces">4.2</a>).</p><!--CUT END -->
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
</html>
|