├── .gitignore ├── COPYING ├── LICENSE-MPL-rabbitmq-lvc-plugin ├── Makefile ├── README.md ├── include └── rabbit_lvc_plugin.hrl ├── package.mk └── src ├── rabbit_exchange_type_lvc.erl ├── rabbit_lvc_plugin.erl └── rabbitmq_lvc.app.src /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | *.beam 4 | 5 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This package, rabbitmq-lvc-plugin, an exchange type plugin for use 2 | with RabbitMQ, is licensed under the MPL. For the MPL, please see 3 | LICENSE-MPL-rabbitmq-lvc-plugin. 4 | 5 | If you have any questions regarding licensing, please contact 6 | info@rabbitmq.com. 7 | -------------------------------------------------------------------------------- /LICENSE-MPL-rabbitmq-lvc-plugin: -------------------------------------------------------------------------------- 1 | MOZILLA PUBLIC LICENSE 2 | Version 1.1 3 | 4 | --------------- 5 | 6 | 1. Definitions. 7 | 8 | 1.0.1. "Commercial Use" means distribution or otherwise making the 9 | Covered Code available to a third party. 10 | 11 | 1.1. "Contributor" means each entity that creates or contributes to 12 | the creation of Modifications. 13 | 14 | 1.2. "Contributor Version" means the combination of the Original 15 | Code, prior Modifications used by a Contributor, and the Modifications 16 | made by that particular Contributor. 17 | 18 | 1.3. "Covered Code" means the Original Code or Modifications or the 19 | combination of the Original Code and Modifications, in each case 20 | including portions thereof. 21 | 22 | 1.4. "Electronic Distribution Mechanism" means a mechanism generally 23 | accepted in the software development community for the electronic 24 | transfer of data. 25 | 26 | 1.5. "Executable" means Covered Code in any form other than Source 27 | Code. 28 | 29 | 1.6. "Initial Developer" means the individual or entity identified 30 | as the Initial Developer in the Source Code notice required by Exhibit 31 | A. 32 | 33 | 1.7. "Larger Work" means a work which combines Covered Code or 34 | portions thereof with code not governed by the terms of this License. 35 | 36 | 1.8. "License" means this document. 37 | 38 | 1.8.1. "Licensable" means having the right to grant, to the maximum 39 | extent possible, whether at the time of the initial grant or 40 | subsequently acquired, any and all of the rights conveyed herein. 41 | 42 | 1.9. "Modifications" means any addition to or deletion from the 43 | substance or structure of either the Original Code or any previous 44 | Modifications. When Covered Code is released as a series of files, a 45 | Modification is: 46 | A. Any addition to or deletion from the contents of a file 47 | containing Original Code or previous Modifications. 48 | 49 | B. Any new file that contains any part of the Original Code or 50 | previous Modifications. 51 | 52 | 1.10. "Original Code" means Source Code of computer software code 53 | which is described in the Source Code notice required by Exhibit A as 54 | Original Code, and which, at the time of its release under this 55 | License is not already Covered Code governed by this License. 56 | 57 | 1.10.1. "Patent Claims" means any patent claim(s), now owned or 58 | hereafter acquired, including without limitation, method, process, 59 | and apparatus claims, in any patent Licensable by grantor. 60 | 61 | 1.11. "Source Code" means the preferred form of the Covered Code for 62 | making modifications to it, including all modules it contains, plus 63 | any associated interface definition files, scripts used to control 64 | compilation and installation of an Executable, or source code 65 | differential comparisons against either the Original Code or another 66 | well known, available Covered Code of the Contributor's choice. The 67 | Source Code can be in a compressed or archival form, provided the 68 | appropriate decompression or de-archiving software is widely available 69 | for no charge. 70 | 71 | 1.12. "You" (or "Your") means an individual or a legal entity 72 | exercising rights under, and complying with all of the terms of, this 73 | License or a future version of this License issued under Section 6.1. 74 | For legal entities, "You" includes any entity which controls, is 75 | controlled by, or is under common control with You. For purposes of 76 | this definition, "control" means (a) the power, direct or indirect, 77 | to cause the direction or management of such entity, whether by 78 | contract or otherwise, or (b) ownership of more than fifty percent 79 | (50%) of the outstanding shares or beneficial ownership of such 80 | entity. 81 | 82 | 2. Source Code License. 83 | 84 | 2.1. The Initial Developer Grant. 85 | The Initial Developer hereby grants You a world-wide, royalty-free, 86 | non-exclusive license, subject to third party intellectual property 87 | claims: 88 | (a) under intellectual property rights (other than patent or 89 | trademark) Licensable by Initial Developer to use, reproduce, 90 | modify, display, perform, sublicense and distribute the Original 91 | Code (or portions thereof) with or without Modifications, and/or 92 | as part of a Larger Work; and 93 | 94 | (b) under Patents Claims infringed by the making, using or 95 | selling of Original Code, to make, have made, use, practice, 96 | sell, and offer for sale, and/or otherwise dispose of the 97 | Original Code (or portions thereof). 98 | 99 | (c) the licenses granted in this Section 2.1(a) and (b) are 100 | effective on the date Initial Developer first distributes 101 | Original Code under the terms of this License. 102 | 103 | (d) Notwithstanding Section 2.1(b) above, no patent license is 104 | granted: 1) for code that You delete from the Original Code; 2) 105 | separate from the Original Code; or 3) for infringements caused 106 | by: i) the modification of the Original Code or ii) the 107 | combination of the Original Code with other software or devices. 108 | 109 | 2.2. Contributor Grant. 110 | Subject to third party intellectual property claims, each Contributor 111 | hereby grants You a world-wide, royalty-free, non-exclusive license 112 | 113 | (a) under intellectual property rights (other than patent or 114 | trademark) Licensable by Contributor, to use, reproduce, modify, 115 | display, perform, sublicense and distribute the Modifications 116 | created by such Contributor (or portions thereof) either on an 117 | unmodified basis, with other Modifications, as Covered Code 118 | and/or as part of a Larger Work; and 119 | 120 | (b) under Patent Claims infringed by the making, using, or 121 | selling of Modifications made by that Contributor either alone 122 | and/or in combination with its Contributor Version (or portions 123 | of such combination), to make, use, sell, offer for sale, have 124 | made, and/or otherwise dispose of: 1) Modifications made by that 125 | Contributor (or portions thereof); and 2) the combination of 126 | Modifications made by that Contributor with its Contributor 127 | Version (or portions of such combination). 128 | 129 | (c) the licenses granted in Sections 2.2(a) and 2.2(b) are 130 | effective on the date Contributor first makes Commercial Use of 131 | the Covered Code. 132 | 133 | (d) Notwithstanding Section 2.2(b) above, no patent license is 134 | granted: 1) for any code that Contributor has deleted from the 135 | Contributor Version; 2) separate from the Contributor Version; 136 | 3) for infringements caused by: i) third party modifications of 137 | Contributor Version or ii) the combination of Modifications made 138 | by that Contributor with other software (except as part of the 139 | Contributor Version) or other devices; or 4) under Patent Claims 140 | infringed by Covered Code in the absence of Modifications made by 141 | that Contributor. 142 | 143 | 3. Distribution Obligations. 144 | 145 | 3.1. Application of License. 146 | The Modifications which You create or to which You contribute are 147 | governed by the terms of this License, including without limitation 148 | Section 2.2. The Source Code version of Covered Code may be 149 | distributed only under the terms of this License or a future version 150 | of this License released under Section 6.1, and You must include a 151 | copy of this License with every copy of the Source Code You 152 | distribute. You may not offer or impose any terms on any Source Code 153 | version that alters or restricts the applicable version of this 154 | License or the recipients' rights hereunder. However, You may include 155 | an additional document offering the additional rights described in 156 | Section 3.5. 157 | 158 | 3.2. Availability of Source Code. 159 | Any Modification which You create or to which You contribute must be 160 | made available in Source Code form under the terms of this License 161 | either on the same media as an Executable version or via an accepted 162 | Electronic Distribution Mechanism to anyone to whom you made an 163 | Executable version available; and if made available via Electronic 164 | Distribution Mechanism, must remain available for at least twelve (12) 165 | months after the date it initially became available, or at least six 166 | (6) months after a subsequent version of that particular Modification 167 | has been made available to such recipients. You are responsible for 168 | ensuring that the Source Code version remains available even if the 169 | Electronic Distribution Mechanism is maintained by a third party. 170 | 171 | 3.3. Description of Modifications. 172 | You must cause all Covered Code to which You contribute to contain a 173 | file documenting the changes You made to create that Covered Code and 174 | the date of any change. You must include a prominent statement that 175 | the Modification is derived, directly or indirectly, from Original 176 | Code provided by the Initial Developer and including the name of the 177 | Initial Developer in (a) the Source Code, and (b) in any notice in an 178 | Executable version or related documentation in which You describe the 179 | origin or ownership of the Covered Code. 180 | 181 | 3.4. Intellectual Property Matters 182 | (a) Third Party Claims. 183 | If Contributor has knowledge that a license under a third party's 184 | intellectual property rights is required to exercise the rights 185 | granted by such Contributor under Sections 2.1 or 2.2, 186 | Contributor must include a text file with the Source Code 187 | distribution titled "LEGAL" which describes the claim and the 188 | party making the claim in sufficient detail that a recipient will 189 | know whom to contact. If Contributor obtains such knowledge after 190 | the Modification is made available as described in Section 3.2, 191 | Contributor shall promptly modify the LEGAL file in all copies 192 | Contributor makes available thereafter and shall take other steps 193 | (such as notifying appropriate mailing lists or newsgroups) 194 | reasonably calculated to inform those who received the Covered 195 | Code that new knowledge has been obtained. 196 | 197 | (b) Contributor APIs. 198 | If Contributor's Modifications include an application programming 199 | interface and Contributor has knowledge of patent licenses which 200 | are reasonably necessary to implement that API, Contributor must 201 | also include this information in the LEGAL file. 202 | 203 | (c) Representations. 204 | Contributor represents that, except as disclosed pursuant to 205 | Section 3.4(a) above, Contributor believes that Contributor's 206 | Modifications are Contributor's original creation(s) and/or 207 | Contributor has sufficient rights to grant the rights conveyed by 208 | this License. 209 | 210 | 3.5. Required Notices. 211 | You must duplicate the notice in Exhibit A in each file of the Source 212 | Code. If it is not possible to put such notice in a particular Source 213 | Code file due to its structure, then You must include such notice in a 214 | location (such as a relevant directory) where a user would be likely 215 | to look for such a notice. If You created one or more Modification(s) 216 | You may add your name as a Contributor to the notice described in 217 | Exhibit A. You must also duplicate this License in any documentation 218 | for the Source Code where You describe recipients' rights or ownership 219 | rights relating to Covered Code. You may choose to offer, and to 220 | charge a fee for, warranty, support, indemnity or liability 221 | obligations to one or more recipients of Covered Code. However, You 222 | may do so only on Your own behalf, and not on behalf of the Initial 223 | Developer or any Contributor. You must make it absolutely clear than 224 | any such warranty, support, indemnity or liability obligation is 225 | offered by You alone, and You hereby agree to indemnify the Initial 226 | Developer and every Contributor for any liability incurred by the 227 | Initial Developer or such Contributor as a result of warranty, 228 | support, indemnity or liability terms You offer. 229 | 230 | 3.6. Distribution of Executable Versions. 231 | You may distribute Covered Code in Executable form only if the 232 | requirements of Section 3.1-3.5 have been met for that Covered Code, 233 | and if You include a notice stating that the Source Code version of 234 | the Covered Code is available under the terms of this License, 235 | including a description of how and where You have fulfilled the 236 | obligations of Section 3.2. The notice must be conspicuously included 237 | in any notice in an Executable version, related documentation or 238 | collateral in which You describe recipients' rights relating to the 239 | Covered Code. You may distribute the Executable version of Covered 240 | Code or ownership rights under a license of Your choice, which may 241 | contain terms different from this License, provided that You are in 242 | compliance with the terms of this License and that the license for the 243 | Executable version does not attempt to limit or alter the recipient's 244 | rights in the Source Code version from the rights set forth in this 245 | License. If You distribute the Executable version under a different 246 | license You must make it absolutely clear that any terms which differ 247 | from this License are offered by You alone, not by the Initial 248 | Developer or any Contributor. You hereby agree to indemnify the 249 | Initial Developer and every Contributor for any liability incurred by 250 | the Initial Developer or such Contributor as a result of any such 251 | terms You offer. 252 | 253 | 3.7. Larger Works. 254 | You may create a Larger Work by combining Covered Code with other code 255 | not governed by the terms of this License and distribute the Larger 256 | Work as a single product. In such a case, You must make sure the 257 | requirements of this License are fulfilled for the Covered Code. 258 | 259 | 4. Inability to Comply Due to Statute or Regulation. 260 | 261 | If it is impossible for You to comply with any of the terms of this 262 | License with respect to some or all of the Covered Code due to 263 | statute, judicial order, or regulation then You must: (a) comply with 264 | the terms of this License to the maximum extent possible; and (b) 265 | describe the limitations and the code they affect. Such description 266 | must be included in the LEGAL file described in Section 3.4 and must 267 | be included with all distributions of the Source Code. Except to the 268 | extent prohibited by statute or regulation, such description must be 269 | sufficiently detailed for a recipient of ordinary skill to be able to 270 | understand it. 271 | 272 | 5. Application of this License. 273 | 274 | This License applies to code to which the Initial Developer has 275 | attached the notice in Exhibit A and to related Covered Code. 276 | 277 | 6. Versions of the License. 278 | 279 | 6.1. New Versions. 280 | Netscape Communications Corporation ("Netscape") may publish revised 281 | and/or new versions of the License from time to time. Each version 282 | will be given a distinguishing version number. 283 | 284 | 6.2. Effect of New Versions. 285 | Once Covered Code has been published under a particular version of the 286 | License, You may always continue to use it under the terms of that 287 | version. You may also choose to use such Covered Code under the terms 288 | of any subsequent version of the License published by Netscape. No one 289 | other than Netscape has the right to modify the terms applicable to 290 | Covered Code created under this License. 291 | 292 | 6.3. Derivative Works. 293 | If You create or use a modified version of this License (which you may 294 | only do in order to apply it to code which is not already Covered Code 295 | governed by this License), You must (a) rename Your license so that 296 | the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", 297 | "MPL", "NPL" or any confusingly similar phrase do not appear in your 298 | license (except to note that your license differs from this License) 299 | and (b) otherwise make it clear that Your version of the license 300 | contains terms which differ from the Mozilla Public License and 301 | Netscape Public License. (Filling in the name of the Initial 302 | Developer, Original Code or Contributor in the notice described in 303 | Exhibit A shall not of themselves be deemed to be modifications of 304 | this License.) 305 | 306 | 7. DISCLAIMER OF WARRANTY. 307 | 308 | COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, 309 | WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, 310 | WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF 311 | DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. 312 | THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE 313 | IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, 314 | YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE 315 | COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER 316 | OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF 317 | ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 318 | 319 | 8. TERMINATION. 320 | 321 | 8.1. This License and the rights granted hereunder will terminate 322 | automatically if You fail to comply with terms herein and fail to cure 323 | such breach within 30 days of becoming aware of the breach. All 324 | sublicenses to the Covered Code which are properly granted shall 325 | survive any termination of this License. Provisions which, by their 326 | nature, must remain in effect beyond the termination of this License 327 | shall survive. 328 | 329 | 8.2. If You initiate litigation by asserting a patent infringement 330 | claim (excluding declatory judgment actions) against Initial Developer 331 | or a Contributor (the Initial Developer or Contributor against whom 332 | You file such action is referred to as "Participant") alleging that: 333 | 334 | (a) such Participant's Contributor Version directly or indirectly 335 | infringes any patent, then any and all rights granted by such 336 | Participant to You under Sections 2.1 and/or 2.2 of this License 337 | shall, upon 60 days notice from Participant terminate prospectively, 338 | unless if within 60 days after receipt of notice You either: (i) 339 | agree in writing to pay Participant a mutually agreeable reasonable 340 | royalty for Your past and future use of Modifications made by such 341 | Participant, or (ii) withdraw Your litigation claim with respect to 342 | the Contributor Version against such Participant. If within 60 days 343 | of notice, a reasonable royalty and payment arrangement are not 344 | mutually agreed upon in writing by the parties or the litigation claim 345 | is not withdrawn, the rights granted by Participant to You under 346 | Sections 2.1 and/or 2.2 automatically terminate at the expiration of 347 | the 60 day notice period specified above. 348 | 349 | (b) any software, hardware, or device, other than such Participant's 350 | Contributor Version, directly or indirectly infringes any patent, then 351 | any rights granted to You by such Participant under Sections 2.1(b) 352 | and 2.2(b) are revoked effective as of the date You first made, used, 353 | sold, distributed, or had made, Modifications made by that 354 | Participant. 355 | 356 | 8.3. If You assert a patent infringement claim against Participant 357 | alleging that such Participant's Contributor Version directly or 358 | indirectly infringes any patent where such claim is resolved (such as 359 | by license or settlement) prior to the initiation of patent 360 | infringement litigation, then the reasonable value of the licenses 361 | granted by such Participant under Sections 2.1 or 2.2 shall be taken 362 | into account in determining the amount or value of any payment or 363 | license. 364 | 365 | 8.4. In the event of termination under Sections 8.1 or 8.2 above, 366 | all end user license agreements (excluding distributors and resellers) 367 | which have been validly granted by You or any distributor hereunder 368 | prior to termination shall survive termination. 369 | 370 | 9. LIMITATION OF LIABILITY. 371 | 372 | UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT 373 | (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL 374 | DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, 375 | OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR 376 | ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY 377 | CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, 378 | WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER 379 | COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN 380 | INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF 381 | LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY 382 | RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW 383 | PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE 384 | EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO 385 | THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 386 | 387 | 10. U.S. GOVERNMENT END USERS. 388 | 389 | The Covered Code is a "commercial item," as that term is defined in 390 | 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer 391 | software" and "commercial computer software documentation," as such 392 | terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 393 | C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), 394 | all U.S. Government End Users acquire Covered Code with only those 395 | rights set forth herein. 396 | 397 | 11. MISCELLANEOUS. 398 | 399 | This License represents the complete agreement concerning subject 400 | matter hereof. If any provision of this License is held to be 401 | unenforceable, such provision shall be reformed only to the extent 402 | necessary to make it enforceable. This License shall be governed by 403 | California law provisions (except to the extent applicable law, if 404 | any, provides otherwise), excluding its conflict-of-law provisions. 405 | With respect to disputes in which at least one party is a citizen of, 406 | or an entity chartered or registered to do business in the United 407 | States of America, any litigation relating to this License shall be 408 | subject to the jurisdiction of the Federal Courts of the Northern 409 | District of California, with venue lying in Santa Clara County, 410 | California, with the losing party responsible for costs, including 411 | without limitation, court costs and reasonable attorneys' fees and 412 | expenses. The application of the United Nations Convention on 413 | Contracts for the International Sale of Goods is expressly excluded. 414 | Any law or regulation which provides that the language of a contract 415 | shall be construed against the drafter shall not apply to this 416 | License. 417 | 418 | 12. RESPONSIBILITY FOR CLAIMS. 419 | 420 | As between Initial Developer and the Contributors, each party is 421 | responsible for claims and damages arising, directly or indirectly, 422 | out of its utilization of rights under this License and You agree to 423 | work with Initial Developer and Contributors to distribute such 424 | responsibility on an equitable basis. Nothing herein is intended or 425 | shall be deemed to constitute any admission of liability. 426 | 427 | 13. MULTIPLE-LICENSED CODE. 428 | 429 | Initial Developer may designate portions of the Covered Code as 430 | "Multiple-Licensed". "Multiple-Licensed" means that the Initial 431 | Developer permits you to utilize portions of the Covered Code under 432 | Your choice of the NPL or the alternative licenses, if any, specified 433 | by the Initial Developer in the file described in Exhibit A. 434 | 435 | EXHIBIT A -Mozilla Public License. 436 | 437 | ``The contents of this file are subject to the Mozilla Public License 438 | Version 1.1 (the "License"); you may not use this file except in 439 | compliance with the License. You may obtain a copy of the License at 440 | http://www.mozilla.org/MPL/ 441 | 442 | Software distributed under the License is distributed on an "AS IS" 443 | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 444 | License for the specific language governing rights and limitations 445 | under the License. 446 | 447 | The Original Code is rabbitmq-lvc-plugin. 448 | 449 | The Initial Developers of the Original Code are LShift Ltd and 450 | Michael Bridgen. 451 | 452 | Portions created by LShift Ltd or Michael Bridgen are Copyright 453 | (C) 2009-2010 LShift Ltd, Michael Bridgen. 454 | 455 | All Rights Reserved. 456 | 457 | Contributor(s): ______________________________________.'' 458 | 459 | [NOTE: The text of this Exhibit A may differ slightly from the text of 460 | the notices in the Source Code files of the Original Code. You should 461 | use the text of this Exhibit A rather than the text found in the 462 | Original Code Source Code for Your Modifications.] 463 | 464 | 465 | 466 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include ../umbrella.mk 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Last value caching exchange 2 | 3 | (**NB**: Simon keeps a fork of this which is more likely to be up-to-date with 4 | RabbitMQ releases, at 5 | https://github.com/simonmacmullen/rabbitmq-lvc-plugin) 6 | 7 | This is a pretty simple implementation of a last value cache using 8 | RabbitMQ's pluggable exchange types feature. 9 | 10 | The last value cache is intended to solve problems like the following: 11 | say I am using messaging to send notifications of some changing values 12 | to clients; now, when a new client connects, it won't know the value 13 | until it changes. 14 | 15 | The last value exchange acts like a direct exchange (binding keys are 16 | compared for equality with routing keys); but, it also keeps track of 17 | the last value that was published with each routing key, and when a 18 | queue is bound, it automatically enqueues the last value for the 19 | binding key. 20 | 21 | # How to build it 22 | 23 | Set up rabbitmq-public-umbrella, as per the instructions 24 | at http://www.rabbitmq.com/plugin-development.html: 25 | 26 | $ hg clone http://hg.rabbitmq.com/rabbitmq-public-umbrella 27 | $ cd rabbitmq-public-umbrella ; make checkout ; make 28 | 29 | Then get the LVC plugin and symlink it into plugins: 30 | 31 | $ git clone git://github.com/squaremo/rabbitmq-lvc-plugin.git 32 | $ (cd rabbitmq-lvc-plugin ; make) 33 | $ mkdir -p rabbitmq-server/plugins 34 | $ cd rabbitmq-server/plugins 35 | $ ln -s ../../rabbitmq-lvc-plugin ./ 36 | 37 | and finally, run the server: 38 | $ cd .. 39 | $ make run 40 | 41 | In the startup banner you should see a line something like 42 | 43 | starting rabbit_exchange_type_lvc ...done 44 | 45 | To use the LVC exchange, with e.g., py-amqp: 46 | 47 | import amqplib.client_0_8 as amqp 48 | ch = amqp.Connection().channel() 49 | ch.exchange_declare("lvc", type="x-lvc") 50 | ch.basic_publish(amqp.Message("value"), 51 | exchange="lvc", routing_key="rabbit") 52 | ch.queue_declare("q") 53 | ch.queue_bind("q", "lvc", "rabbit") 54 | print ch.basic_get("q").body 55 | 56 | # Limitations 57 | 58 | ## "Recent value cache" 59 | 60 | AMQP is inherently racey. It is quite possible to see different 61 | last-values but the same subsequent message stream, from different 62 | clients. 63 | 64 | This won't matter if you simply want to have a value to show until you 65 | get an update. If it does matter, consider e.g. using sequence IDs so you 66 | can notice out-of-order messages. 67 | 68 | There's also a race in the pluggable exchanges hook, so that clients 69 | can "see" the binding before the hook has been run; for the LVC, this 70 | means that there's a possiblity that messages will get queued before 71 | the last value. For this reason, I'm thinking of tagging the last 72 | value messages so that clients can fast-forward to it, or ignore it, 73 | if necessary. 74 | 75 | ## Values v. deltas 76 | 77 | One question that springs to mind when considering last value caches 78 | is "what if I'm sending deltas rather than the whole value?". Thre 79 | LVC exchange doesn't address this use case, but you could do it by 80 | using two exchanges and posting full values to the LVC (from the 81 | originating process -- presumably you'd be using deltas to save on 82 | downstream bandwidth). 83 | 84 | ## Direct exchanges only 85 | 86 | The semantics of another kind of value-caching exchange (other than 87 | fanout) aren't obvious. To choose one option though, say a 88 | newly-bound queue was to be given all values that match its binding 89 | key -- this would require every supported exchange type to supply a 90 | reverse routing match procedure. 91 | -------------------------------------------------------------------------------- /include/rabbit_lvc_plugin.hrl: -------------------------------------------------------------------------------- 1 | -define(LVC_TABLE, lvc). 2 | 3 | -record(cachekey, {exchange, routing_key}). 4 | -record(cached, {key, content}). 5 | -------------------------------------------------------------------------------- /package.mk: -------------------------------------------------------------------------------- 1 | APP_NAME=rabbitmq_lvc 2 | DEPS=rabbitmq-server rabbitmq-erlang-client 3 | -------------------------------------------------------------------------------- /src/rabbit_exchange_type_lvc.erl: -------------------------------------------------------------------------------- 1 | -module(rabbit_exchange_type_lvc). 2 | -include_lib("rabbit_common/include/rabbit.hrl"). 3 | -include("rabbit_lvc_plugin.hrl"). 4 | 5 | -behaviour(rabbit_exchange_type). 6 | 7 | -export([description/0, serialise_events/0, route/2]). 8 | -export([validate/1, create/2, recover/2, delete/3, 9 | add_binding/3, remove_bindings/3, assert_args_equivalence/2]). 10 | 11 | -include_lib("rabbit_common/include/rabbit_exchange_type_spec.hrl"). 12 | 13 | description() -> 14 | [{name, <<"lvc">>}, 15 | {description, <<"Last-value cache exchange.">>}]. 16 | 17 | serialise_events() -> false. 18 | 19 | route(Exchange = #exchange{name = Name}, 20 | Delivery = #delivery{message = #basic_message{ 21 | routing_keys = RKs, 22 | content = Content 23 | }}) -> 24 | Keys = case RKs of 25 | CC when is_list(CC) -> CC; 26 | To -> [To] 27 | end, 28 | rabbit_misc:execute_mnesia_transaction( 29 | fun () -> 30 | [mnesia:write(?LVC_TABLE, 31 | #cached{key = #cachekey{exchange=Name, 32 | routing_key=K}, 33 | content = Content}, 34 | write) || 35 | K <- Keys] 36 | end), 37 | rabbit_exchange_type_direct:route(Exchange, Delivery). 38 | 39 | validate(_X) -> ok. 40 | create(_Tx, _X) -> ok. 41 | recover(_X, _Bs) -> ok. 42 | 43 | delete(transaction, #exchange{ name = Name }, _Bs) -> 44 | [mnesia:delete(?LVC_TABLE, K, write) || 45 | #cached{ key = K } <- 46 | mnesia:match_object(?LVC_TABLE, 47 | #cached{key = #cachekey{ 48 | exchange = Name, _ = '_' }, 49 | _ = '_'}, write)], 50 | ok; 51 | delete(_Tx, _X, _Bs) -> 52 | ok. 53 | 54 | add_binding(none, #exchange{ name = XName }, 55 | #binding{ key = RoutingKey, 56 | destination = QueueName }) -> 57 | case rabbit_amqqueue:lookup(QueueName) of 58 | {error, not_found} -> 59 | rabbit_misc:protocol_error( 60 | internal_error, 61 | "could not find queue '~s'", 62 | [QueueName]); 63 | {ok, #amqqueue{ pid = Q }} -> 64 | case mnesia:dirty_read( 65 | ?LVC_TABLE, 66 | #cachekey{ exchange=XName, 67 | routing_key=RoutingKey }) of 68 | [] -> 69 | ok; 70 | [#cached{content = Content}] -> 71 | {Props, Payload} = 72 | rabbit_basic:from_content(Content), 73 | Msg = rabbit_basic:message( 74 | XName, RoutingKey, Props, Payload), 75 | rabbit_amqqueue:deliver( 76 | Q, rabbit_basic:delivery(false, false, Msg, undefined)) 77 | end 78 | end, 79 | ok; 80 | add_binding(_Tx, _X, _B) -> 81 | ok. 82 | 83 | remove_bindings(_Tx, _X, _Bs) -> ok. 84 | 85 | assert_args_equivalence(X, Args) -> 86 | rabbit_exchange_type_direct:assert_args_equivalence(X, Args). 87 | -------------------------------------------------------------------------------- /src/rabbit_lvc_plugin.erl: -------------------------------------------------------------------------------- 1 | -module(rabbit_lvc_plugin). 2 | 3 | -include("rabbit_lvc_plugin.hrl"). 4 | 5 | -export([setup_schema/0]). 6 | 7 | -rabbit_boot_step({?MODULE, 8 | [{description, "last-value cache exchange type"}, 9 | {mfa, {rabbit_lvc_plugin, setup_schema, []}}, 10 | {mfa, {rabbit_registry, register, [exchange, <<"x-lvc">>, rabbit_exchange_type_lvc]}}, 11 | {requires, rabbit_registry}, 12 | {enables, recovery}]}). 13 | 14 | %% private 15 | 16 | setup_schema() -> 17 | case mnesia:create_table(?LVC_TABLE, 18 | [{attributes, record_info(fields, cached)}, 19 | {record_name, cached}, 20 | {type, set}]) of 21 | {atomic, ok} -> ok; 22 | {aborted, {already_exists, ?LVC_TABLE}} -> ok 23 | end. 24 | -------------------------------------------------------------------------------- /src/rabbitmq_lvc.app.src: -------------------------------------------------------------------------------- 1 | {application, rabbitmq_lvc, 2 | [{description, "RabbitMQ last value cache exchange plugin"}, 3 | {vsn, "0.0.2"}, 4 | {modules, [ 5 | rabbit_lvc_plugin, 6 | rabbit_exchange_type_lvc 7 | ]}, 8 | {registered, []}, 9 | {env, []}, 10 | {applications, [kernel, stdlib, rabbit, mnesia]}]}. 11 | --------------------------------------------------------------------------------