text:
Sunday, 24 June 2007
Angélique - Claude-Alain Bugnon's New Verte Suisse Absinthe
Officially launched at the Boveresse Absinthe Festival, Angélique is now also available from absinthe-suisse.com. It is the first Verte created by Claude-Alain Bugnon of La Clandestine fame and is in response to many customer requests for a "véritable Verte Suisse."
Distilled using 12 plants, it is named Angélique partly after Claude-Alain's daughter and partly because it contains angelica. However, as Claude-Alain says, this new absinthe has both an angelic aspect and perhaps one that is almost .... "devilish." Angélique may be the natural daughter of his original Charlotte La Clandestine (named after Charlotte Vaucher, the original inventor of that absinthe's recipe), but she is evidently a rebellious daughter, judging by her impish appearance on the new label! Charlotte and the distillery also feature, echoing the original Clandestine label.
Angélique itself is slightly more bitter than La Clandestine and takes it natural colour from the aromatic plants of the Val-de-Travers region which are steeped in the distillate.
In fact, Angélique has been privately offered to a few of Claude-Alain's friends both in Switzerland and via the internet in recent months. Their response has been overwhelmingly positive, with reviews such as:
"Oh my....we just tried it. You have created a wonderful new verte. That smells wonderful and tastes incredibly delicious. Congratulations on one of the best I have tasted in the vertes. We already love the CLB! When can we "talk" about this product on the Wormwood Society website? Best to you. This is outstanding!" ..... "Our desert island absinthe." (B & C, Washington).
"The most amazing quality of this verte suisse is its mouth feel, truly like nothing I've drank before. Louche is beautiful, perfect. Great with sugar! Sweet, bitter, and very aromatic, Angelique is my new favorite, even my friends preferred it when i let them sample my absinthes (their first time)." (K, California)
"I thought the Angelique was terrific. It was well-balanced with just the right amount of wormwood." (J, Nevada)
"I want to congratulate Claude-Alain on the Angélique. It's wonderful! I hope it'll be going into full production soon so that I can rave about it on the forum! It's definitely my favorite verte of the ones I've tried so far, superceding the Jades which constitute my only reference. If Artemisia is aiming for a monopoly, well, you're quite close to having one in my book. :) I think I'm going to start telling my friends absinthe is a Swiss beverage." (D, New Mexico)
And my favourite review, just in:
"I will treat the description of this bottle as though it were made just for
me because it is that good. The graphic designer has gone above and beyond
with the label. It is beautiful and captures a mood that is befitting such
an amazing recipe as this. It must have been the fairies that contributed
to the herb selection and balance because it could only be through magic or
an extremely sensitive pallet that this combination could have been
The smell as the bottle is opened the first time is strong and reeks of the
essence of absinthe as it ought to be.
The louche is perfect and beautiful. As it is difficult to determine the
rations the first time an absinthe is mixed, I used the method I always use.
I slowly drip the spring water from my fountain until it is entirely
opaque; only then do I stop and I stop exactly then.
I suggest smelling this with your eyes closed to see what the
smell evokes as I did. It is olfactory perfection.
The taste of this absinthe is just as absinthe was meant to be. It
accomplishes what many other absinthes are obviously trying to accomplish.
It is a refined combination that makes no attempts at being overly complex
just to stand out. The subtle tincture of background herbs dances around
the dominant flavors in such a way that there is no competition. It is
drinking a bottle of harmony.
The mouth feel of this absinthe has just the right amount of bite even when
diluted. I can feel it working as the flavor passes over my tongue. The
aftertaste of this fine mixture is of strong anise. I have grown to adore
anise over the last several years of drinking absinthe so it is as though it
is still in my mouth long after I have lamentable pleasure of swallowing my
last sip.
I am greatly pleased that Claude-Alan has turned his expertise to the
absinthes verte as they have always been my favorites. Thank you for the
pleasure I have had this evening." (N, Colorado)
A forum friend toasts Claude-Alain at the launch in Couvet
Given these comments, Claude-Alain was delighted to be able to launch it in time for Boveresse. At a time when other absinthe distillers may be focused on the bigger volume opportunities perhaps available in the USA, it is good to see at least one artisan sticking to his roots.
Note: Angélique was originally released at 72% abv, and some of the photos in this article show that label. The top photo shows the latest 68% abv label.
Posted by Alan at 13:37
Labels: La Clandestine, news
1 comment:
- The Absinthe Review Network said...
We loved the Angelique Verte Suisse! Just ordered a bottle of the a24 tweaked version last Saturday, so I'll be waiting eagerly by the porch every afternoon until it arrives...
- 1 July 2008 at 13:39
Subscribe to: Post Comments (Atom)


text:
The Geography Blog focusing on all things geography: human, physical, technical, space, news, and geopolitics. Also known as Geographic Travels with Catholicgauze! Written by a former National Geographic employee who also proudly served in Iraq and Afghanistan.
Saturday, February 03, 2007
IPCC Report
In 1970, as the first Earth Day approached, Paul Ehrlich wrote an article in The Progressive as a fictitious report to the US President, looking back from the year 2000. The ostensible report underlines how environmentalist scientists in the 1960s and 1970s had "repeatedly pointed out" that overcrowding, hunger and environmental deterioration would lead to "environmental and public health disasters." Unfortunately, people had not heeded the warnings, and Ehrlich tells us of a US that is almost unrecognizable, with a severely decimated population at 22.6 million (8 percent of current population) with a diet of 2,400 daily calories per person (less than the current African average). As an almost ironic glimmer of hope, Ehrlich does not expect that the US is faced with any immediate limits-to-growth threat of running out of resources, because of the "small population size and continued availability of salvageable materials in Los Angeles and other cities which have not been reoccupied."
The United Nations' Intergovernmental Panel on Climate Change has released a report (PDF) on climate change with much media fan fare. The press hyped it as proving human-caused global warming and saying there are only ten years left to avoid disaster. A National Geographic News story started off with "Global warming is here, it's human-caused..." National Geographic News followed up with a story which hinted at the IPCC report may not be predicting Doomsday enough. Other events coincided with the summary release like Paris voluntarily going lights out for five minutes (after the five minutes they resumed normal polluting practices). Prince Charles celebrated his green-ness by accepting an environmentalist award (which he used a private jet that spews out 10,000 pounds of carbon dioxide an hour!)
But before you built your new house on the tallest mountain or construct Arc 2.0 you may want to learn some things.
First the report does not sit well with the global warming litany, it only is being spun like so. It disagrees with the likes of Al Gore and others by not firmly coming down on human-caused global warming. Gore and crew would like you to think there is no doubt what so ever on human-caused dramatic global warming. Robert Christopherson would go so far to yell at you and make you talk to polar bears while Heidi Cullen would strip you of all scientific rights if you did not believe in 100% human-caused dramatic global warming. To be fair the report says human-caused global warming is "very likely" man made but the fact that these scientists could not pin it down and used weasel words says something. Secondly it says global warming would continue for centuries with or without human behavioral changes. Sure this is bad but did not Al Gore say at the end of his Oscar-nominated movie which qualified him for the Nobel Peace Prize that simple and moderate changes would greatly stop global warming? Division exists in the debate, always remember that.
Catholicgauze read the report and was disappointed. No where does the report address why global warming started in the 1850s at a similar rate it advances today while human-activity was much lower than. Nowhere does it try to determine why there were several cold-snaps in the warming trend. A decrease in global mean temperature from 1900 to 1910 negated all gains from 1850 to 1900. A sudden rise in the 1930s which disasters like the dust bowl can partially be blamed on was canceled out from 1940 to the 1970s (remember global cooling?). Also not considered are previous dramatic climate changes like the Little Ice Age and the fact global warming is occurring on other planets.
Climate Change has the potential to be a serious problem, as described by Harm de Blij. However, when "leading" scientists still cannot find blame enough to convict debate is open to causes. Instead of wasting time trying to find blame and using it as a political tool to enforce treaties which impose no regulations on serious offenders like China and India, let us spend resources on efforts to prepare any needed adaption. If one believes the IPCC report, this is the only reasonable option. Wineries once existed in England and Scotland but natural climate change put an end to that during the Little Ice Age. I am not saying we should not worry about climate change. One warming trend ended the last Ice Age and raised sea levels over 300 feet so there are hazards. All I am saying is we need to be realistic and not join a Robert Christopherson-style cult of global warming.
I will leave with some news which may ease a little bit of fear. As pointed out in "Planning for sea level rise and shore protection under climate uncertainty" by Gary Yohe and James Neuman in Climatic Change in Volume 37 on page 250 estimate for sea level rise have been steadily decreasing. They were once estimated by the Environmental Protection Agency to rise 2 meters (six and a half feet!). No one today comes anywhere close to that, the IPCC only estimates 7 inches to slightly under 2 feet (talk about a margin-of-error).
If the weather man has problems getting tomorrow's weather correct imagine the problems with predicting 100 years into the future.
One geologist said this of Al Gore, "What he's doing is no less than the scare tactics used by people like Karl Rove." Dang! Finally, Delaware's chief climatologist is taking a stand against the Global Warming mania. Here is a skeptical wrap-up of other global warming going ons.
9 comments:
- Jay@Soob said...
Thanks for providing some refreshing, non-hysterical analysis of an issue otherwise immersed in a maelstrom of rhetoric.
Further appreciated is your recognition of the virtual ignorance regarding the need to prepare for what might well be inevitable and natural. Excellent as always.
I dont even know where to begin. Global warming is taking place people. Get it into your dense heads. The vast majority of the scientific community recognize this. The only ones who dont are the likes of Bjorn Lomborg, Bush and oil companies. Science cannot be 100% sure in many issues, however it can offer a far better answer than anything else. So when scientists say that Global Warming is human caused with 90% surity, I would like for someone to provide scientific data to dispute that rather than say no for god knows what reason. Statisticians (not true environmental scientists) like Lomborg might dispute this, but the vast majority of scientists (and we're not talking 51% here) have for the most part discredited him. How can we fix a problem when we have people who do not even recognize it exists. To me personally, not recognizing that global warming is happening due to human activity is just as ludicrous as sounding like the Iranian president who denies the Jewish holocaust ever happened. In both cases the nay sayers are a minority, but the sheer ignorance still exists. It is of no surprise that the nay sayers use scientific data that in most cases is produced by SCIENTISTS who are hired by oil companies because of a vested interest. What vested interests would environmental researchers have other than to speak the truth. If global warming was not happening, then they would find another research topic to work on. But for oil companies, they have to protect their source of income until it runs out. Probably then will they recognize that, 'oh shit, global warming does really exist.' In conclusion, I recognize that the scientists might be wrong, however, the chances of that wrong are slim to none. If they happen to be wrong in the future, what is the worse thing that would have happened, other than us protecting mother earth for a bit longer. If they are right and we dont take action, the worse thing that can happen is that we really get screwed. Finally, I have to agree that China and India have to sign deals to reduce emissions. So far, they have been reluctant to sign the Kyoto Protocol just like the U.S. However, for the U.S. to use that as an excuse for not signing the protocol is simply childish. I will not do it because you will not do it. The U.S. is the single biggest contributor to CO2 emissions (25-30%). India and China dont even come close although they support 8 times the population the U.S. does. If the U.S. wants to be a true global leader (not just military), I suggest we start acting more responsibly. So if the nay sayers still want to deny what is most likely happening to the environment, no amount of logic can make sense to them.
- Catholicgauze said...
Thanks! Your blogging thoughts are great as well.
I am making a whole post as a reply to your comment. Prepare to be Catholicgauzed!
- Adrian said...
"Global warming has happened forever, natural cycle, blah blah blah."
So what? If it is happening (I'll go with the scientists on this one) then we need to make it stop. Climate change will lead to tremendous hardship and suffering and may even decrease the number of human beings this planet can support. Thus we need to stop it. If it is being caused partially (whether 10% or 90%) by human activity, we need to stop it. If it is caused naturally, we need to figure out some way to reverse it.
- Adrian said...
Also, forgot to add, that I think the distinction between "natural" and "man-made" is totally bogus. Man-made causes are a subset of natural causes. Making an explicit distinction merely perpetuates our dream of being totally unreliant on our environment and on things (partially/mostly/totally) out of our control. Man is a subset of nature.
- Catholicgauze said...
"If it is happening (I'll go with the scientists on this one) then we need to make it stop."
If global warming is mostly human caused there may be the moral and survival reasons to make it stop. However, if this warming trend is natural why must it be stopped? How many times have we been told and learned the hard way that standing in the way of nature leads to bad things?
What if global warming can be a good thing [1] regardless if it is man-made or natural?
As for your second part read the two man in/above nature posts [2]for my thoughts.
[1]Global Warming Good?.
- Adrian said...
That canada.com article didn't actually list any benefits Tol thought of, it just mentioned that there might be some.
There are plenty of natural phenomena that are disadvantageous to our survival as a species. Climate change is one, species extinction is another, natural disasters, etc. "Natural" is not a synonym for "good." Over history, most species that have existed have also naturally gone extinct.
There are plenty of examples of when humans have "stood in the way of nature." Damming rivers, building dikes, genetic engineering, etc.
- Catholicgauze said...
I think I didn't make my point clear. You used the example of how flooding can be a natural thing which is bad. Well sometimes (and I stress sometimes) damming in the long run can cause even more problems like a worse flood. You say we must stop global warming. Maybe we should (if it is even possible) but one must bear in mind our fix might only be temporary.
And what happens if there can be more winners than losers in global warming? Dr. Barrnet hints at that. Should Global Warming be stopped then?
- Dan tdaxp said...
I'm guessing that Adrian and Catholicgauze agree 100%.
Catholicgauze is criticizing the view that "man makes nature change" by noting how we really don't know.
Adrian is criticizing the view that "man is bad" by pointing out that often nature is bad as well.

subset: commoncrawl


text:
What are your Guests Experiencing?
Every aspect of their experience is important and can increase spending, impact return visits and drive social media. Our tools help you Measure your guest experience, Analyze the results and take Action!
Amusement / Theme Parks
"Amusement Advantage has been a great partner in providing feedback. Their evaluations are timely and actionable. Our decision to utilize them has proven to be a great investment."
– Craig Freeman: Cedar Fair Entertainment
– Craig Freeman: Cedar Fair Entertainment
"The mystery shopping reports give us great insight into the guest experience and are invaluable in improving the way we interact with our visits. We highly recommend their services."
– Caroline Fly: Aquarium of the Pacific
– Caroline Fly: Aquarium of the Pacific
Family Entertainment Centers
"Amusement Advantage has proven to stand out above their competition. I would recommend anyone looking to implement an affordable Secret Shopper program to consider them!"
– Gregg Borman: Apex Parks Group
– Gregg Borman: Apex Parks Group
Museums / Science Centers
"The reports we receive are very detailed and thorough, which helps us identify where we can improve and where we are meeting and exceeding our guest's expectations."
– Stephanie Wood: Denver Museum of Nature & Science
– Stephanie Wood: Denver Museum of Nature & Science
Skating Centers
"We worked closely to develop a specific shopper report that fits the needs of our company. We fine tune our shops on a regular basis and they work with us to accomplish our goals. I highly recommend them."
– Bruce Aster: United Skates of America
– Bruce Aster: United Skates of America
Water Parks
"The thorough and useful reports are a great snapshot of what the guests' entire experience is. It is a great addition to our in house surveying and we continue to find it well worth our investment."
– Terri Adams: Schlitterbahn Waterparks & Resorts
– Terri Adams: Schlitterbahn Waterparks & Resorts
"We selected Amusement Advantage based upon their demonstrated integrity, attention to detail, flexibility, and national presence. They have proven on numerous occasions that they can handle a variety of demands in a wide range of cultural attractions."
– Tim Brantley: Service Systems Associates
– Tim Brantley: Service Systems Associates
Shopper Warning
Beware of various check and money order cashing scams using our company name! Click here for details.
Obtain objective detailed feedback from real customers in your market with mystery shopping evaluations and guest surveys, customized to your organizations needs.
Discover actionable insight through comprehensive reporting, historical comparison data, industry benchmarking, in-depth performance analysis and public feedback analysis.


text:
(written from a Production point of view)
Robert S. Pickering is an Aviation Electronics Technician 1st Class from the USS Enterprise CVN-65 who was named "Sailor of the Year" in 2001 along with fellow sailors Sara Elizabeth Pizzo and Timothy J. Whittington. Together they received featured cameo parts as engineers aboard Enterprise NX-01 in the Star Trek: Enterprise first season episode "Desert Crossing". Following their work in front of the camera they presented a plaque to Rick Berman and Brannon Braga.
Pickering's uniform was sold off on the It's A Wrap! sale and auction and was also worn by regular background actor Jef Ayres and stuntman Keii Johnston. [1]


text:
Urban or rural?
Gran Canaria's urban cities and plush beach resorts compete with the diverse landscapes of volcanic mountains and tropical forests.
Gran Canaria's urban cities and plush beach resorts compete with the diverse landscapes of volcanic mountains and tropical forests.
Much more than just a holiday by the beach, Gran Canaria offers an appealing array of year-round temperatures, awe-inspiring landscapes and an endless coastline. Indulge the senses – relax on the beach, hike the wilderness or enjoy the renowned nightlife.
Enjoy the spectacular beauty of the unspoilt sand dunes of Maspalomas, trek through the inland forested regions searching for volcanoes like the Montañón Negro. Bask on the beach at Playa del Ingles, or go shopping in the luxury stores of Meloneres. Head north for the cultural centre of Las Palmas and enjoy delicious cuisine with the cosmopolitan crowds. The varied nightlife options on the island cater for everyone, from quiet cantinas to raucous club nights until dawn. And don't forget to try some water sports, as you are surrounded by the Atlantic Ocean.
Gran Canaria is great for shopping, it's much cheaper than mainland Europe and has the same selection of shops you would find in any city – like Zara and H&M. Las Palmas is the place to go, especially Il Corte Inglés, a large department store which offers a 10% discount to all tourists. Head down south to swanky Meloneres to find high-end boutiques, and afterwards drink a cocktail or two on the beach.
Get stuck into the history and culture of Gran Canaria as you see the sights. Learn about traditional agriculture at Museo de la Zafra or see fascinating historical relics at the Museo Canario. Enjoy an interactive experience at Museo Elder de la Ciencia y la Tecnologia, whose motto is 'forbidden not to touch'. And don't miss the tropical gardens of the Parque Botánico de Maspalomas.
Discover cuisine to satisfy all taste buds in Gran Canaria. From the affordable international cuisine of Playa del Ingles to the authentic tapas bars of San Fernando. Dine on freshly caught seafood in Agaete or sample Papas Arrugadas, a Canarian delicacy. The island's tropical climate means that delicious, exotic fruit is grown locally and is readily available.
Dance the night away in Playa del Ingles, where the lively nightlife attracts the party crowd. Embrace a more upmarket vibe in Maspalomas as you enjoy a leisurely meal and cocktails, or absorb the Canarian flavour of Las Palmas. If you're feeling lucky pay a visit to the casino at either Hotel Santa Catalina or Hotel Melia Tamarindos.
Maspalomas is perhaps Gran Canarias's most popular beach, especially in the summer months. But the volcanic sands of Playa de San Agustin offer a more peaceful atmosphere. Playa del Ingles is a hive of activity with its lively water sports and energetic vibe, but to get the most sunshine on the island visit Puerto Rico Beach.
Gran Canaria has a lot of Senderos (trails) criss-crossing its beautifully diverse landscape. One hour you could be trekking through tree-lined pathways and the next scaling a volcanic bluff. See the stunning Dunas de Maspalomas or head inland to the Parque Natural de Pilancones, whose landscape changes from cactus-filled desert to pine forests.
Find a British Airways flight for less, we'll refund the difference.
Fly with British Airways and enjoy award-winning service, excellent value for money and no hidden charges:


text:
Darren Tate under his multi hit making Jurgen Vries alias opens his 2014 account in style with the behemoth 'Alive'. Already famed for hits such as "The Theme", "The Opera Song", "Wilderness" and "Take My Hand" the Jurgen Vries moniker has been synonymous with massive inventive club cuts and "Alive" is no exception.
With its unique and crisp fusion of genres that's sure to deliver a genuine invasion of your senses this is classic Jurgen Vries with production wizardry and diverse craftsmanship. Whilst keeping things super cool, 'Alive' features a huge vocal hook, quirky leads and stomping grooves that are bound to please the masses.
If that wasn't enough, we have a barrage of remixes ready and armed for all your club eventualities. The club mix returns to earth and fires up the energy taking the track in a new direction with its cool cut progressive house grooves, followed up by a deep and dirty alternative from 8 Ball.
- Original Mix
- Club Mix
- 8 Ball Remix
- 8 Ball Instrumental Mix
- Radio Edit
MND162CD: Jurgen Vries feat. Desi Valentine - Alive
- Product Code: MND162CD
- Availability: In Stock
- Ex Tax: £2.49


text:
MIAMI – Police are looking the burglars who broke into a Sprint store in west Miami-Dade.
The burglary happened at Vidal Communication, a Sprint store, located at 8766 W. Flagler Street, overnight Friday.
Police say the burglar smashed the glass door of the business and then stole an iPad mini, an iPad, an iPhone 4, and several other smartphones. The stolen devices are worth about $2,400.
Detectives were looking at surveillance video from the store.
Smartphones have become a hot commodity for crooks.
Two weeks ago, surveillance video recorded a robbery at a Radio Shack in Pompano Beach, where three armed men stormed into the store and stole bags of iPhone 5s.


text:
Free Ground Shipping on Orders of $150 or More! Use Coupon Code: SHIPFREE820
Terms and Conditions. This offer for free shipping and handling applies to ground ship orders over $150 and is valid for orders placed online at www.etundra.com from 08/10/2020 12:00:00 AM thru 08/14/2020 11:59:59 PM MST. This offer applies to standard ground shipping and handling within the U.S., excluding Hawaii, Alaska and U.S. Territories (other than Washington, D.C.). LTL/freight shipments are not eligible for this offer and may be subject to additional shipping and handling charges. Customers are responsible for all taxes and for all Rush Delivery upgrade fees for 3-Day Express, 2-Day Express and Next Day Delivery. Tundra Restaurant Supply reserves the right to modify or discontinue this offer at any time. Void where prohibited by law. This coupon does not apply to previous purchases, can only be applied to the website(s) listed above, and cannot be combined with other offers. The coupon code will need to be added to the shopping cart or during the checkout process.
Whether you're a seasoned chef or a new-to-the-trade amateur, kitchen strainers come in handy in any kitchen. They're inexpensive, easy to use, and when you don't have one… you'll wish you did. That's why picking kitchen strainers up that'll get you through both big and small kitchen adventures is an important piece in your ever-evolving culinary puzzle. From small 4" strainers to larger strainers that go up to 14", a variety of sizes is the way to go to ensure all of your menu items can be thoroughly strained no matter how much you're cooking up.
Enter your email address to receive exclusive
discounts, promotions and advice!
Sign up now to receive $15 OFF your next order!
Copyright © 2020. All Rights Reserved by Tundra Restaurant Supply -
3825 Walnut Street Unit E, Boulder, CO 80301. v 2016.32.7520.20345


text:
Table of Contents
By Pieter Hintjens
With thanks to the hundred or so people who contributed examples in two dozen programming languages, who helped with suggestions and fixes, and who kept pushing for more examples of how to connect your code.
Thanks to Bill Desmarais, Brian Dorsey, Daniel Lin, Eric Desgranges, Gonzalo Diethelm, Guido Goldstein, Hunter Ford, Kamil Shakirov, Martin Sustrik, Mike Castleman, Naveen Chawla, Nicola Peduzzi, Oliver Smith, Olivier Chamoux, Peter Alexander, Pierre Rouleau, Randy Dryburgh, John Unwin, Alex Thomas, Mihail Minkov, Jeremy Avnet, Michael Compton, Kamil Kisiel, Mark Kharitonov, Guillaume Aubert, Ian Barber, Mike Sheridan, Faruk Akgul, Oleg Sidorov, Lev Givon, Allister MacLeod, Alexander D'Archangel, Andreas Hoelzlwimmer, Han Holl, Robert G. Jakabosky, Felipe Cruz, Marcus McCurdy, Mikhail Kulemin, Dr. Gergő Érdi, Pavel Zhukov, Alexander Else, Giovanni Ruggiero, Rick "Technoweenie", Daniel Lundin, Dave Hoover, Simon Jefford, Benjamin Peterson, Justin Case, Devon Weller, Richard Smith, Alexander Morland, Wadim Grasza, Michael Jakl, Uwe Dauernheim, Sebastian Nowicki, Simone Deponti, Aaron Raddon, Dan Colish, Markus Schirp, Benoit Larroque, Jonathan Palardy, Isaiah Peng, Arkadiusz Orzechowski, Umut Aydin, Matthew Horsfall, Jeremy W. Sherman, Eric Pugh, Tyler Sellon, John E. Vincent, Pavel Mitin, Min RK, Igor Wiedler, Olof Åkesson, Patrick Lucas, Heow Goodman, Senthil Palanisami, John Gallagher, Tomas Roos, Stephen McQuay, Erik Allik, Arnaud Cogoluègnes, Rob Gagnon, Dan Williams, Edward Smith, James Tucker, Kristian Kristensen, Vadim Shalts, Martin Trojer, Tom van Leeuwen, Pandya Hiten, Harm Aarts, Marc Harter, Iskren Ivov Chernev, Jay Han, Sonia Hamilton, and Zed Shaw.
Thanks to Stathis Sideris for Ditaa, which I used for the diagrams.
Please use the issue tracker for all comments and errata. This version covers the latest stable release of ØMQ (2.2.x) and was published on Wed 8 August, 2012. If you are using ØMQ/3.1 some of the examples and explanations won't be accurate.
The Guide is originally in C, but also in PHP, Python, Lua, and Haxe. We've also translated most of the examples into C++, C#, CL, Erlang, F#, Felix, Haskell, Java, Objective-C, Ruby, Ada, Basic, Clojure, Go, Haxe, Node.js, ooc, Perl, and Scala.
Chapter One - Basic Stuff
|top prev next
Fixing the World
|top prev next
How to explain ØMQ? Some of us start by saying all the wonderful things it does. It's sockets on steroids. It's like mailboxes with routing. It's fast! Others try to share their moment of enlightenment, that zap-pow-kaboom satori paradigm-shift moment when it all became obvious. Things just become simpler. Complexity goes away. It opens the mind. Others try to explain by comparison. It's smaller, simpler, but still looks familiar. Personally, I like to remember why we made ØMQ at all, because that's most likely where you, the reader, still are today.
Programming is a science dressed up as art, because most of us don't understand the physics of software, and it's rarely if ever taught. The physics of software is not algorithms, data structures, languages and abstractions. These are just tools we make, use, throw away. The real physics of software is the physics of people.
Specifically, our limitations when it comes to complexity, and our desire to work together to solve large problems in pieces. This is the science of programming: make building blocks that people can understand and use easily, and people will work together to solve the very largest problems.
We live in a connected world, and modern software has to navigate this world. So the building blocks for tomorrow's very largest solutions are connected and massively parallel. It's not enough for code to be "strong and silent" any more. Code has to talk to code. Code has to be chatty, sociable, well-connected. Code has to run like the human brain, trillions of individual neurons firing off messages to each other, a massively parallel network with no central control, no single point of failure, yet able to solve immensely difficult problems. And it's no accident that the future of code looks like the human brain, because the endpoints of every network are, at some level, human brains.
If you've done any work with threads, protocols, or networks, you'll realize this is pretty much impossible. It's a dream. Even connecting a few programs across a few sockets is plain nasty, when you start to handle real life situations. Trillions? The cost would be unimaginable. Connecting computers is so difficult that software and services to do this is a multi-billion dollar business.
So we live in a world where the wiring is years ahead of our ability to use it. We had a software crisis in the 1980s, when leading software engineers like Fred Brooks believed there was no "Silver Bullet" to "promise even one order of magnitude of improvement in productivity, reliability, or simplicity".
Brooks missed free and open source software, which solved that crisis, enabling us to share knowledge efficiently. Today we face another software crisis, but it's one we don't talk about much. Only the largest, richest firms can afford to create connected applications. There is a cloud, but it's proprietary. Our data, our knowledge is disappearing from our personal computers into clouds that we cannot access, cannot compete with. Who owns our social networks? It is like the mainframe-PC revolution in reverse.
We can leave the political philosophy for another book. The point is that while the Internet offers the potential of massively connected code, the reality is that this is out of reach for most of us, and so, large interesting problems (in health, education, economics, transport, and so on) remain unsolved because there is no way to connect the code, and thus no way to connect the brains that could work together to solve these problems.
There have been many attempts to solve the challenge of connected software. There are thousands of IETF specifications, each solving part of the puzzle. For application developers, HTTP is perhaps the one solution to have been simple enough to work, but it arguably makes the problem worse, by encouraging developers and architects to think in terms of big servers and thin, stupid clients.
So today people are still connecting applications using raw UDP and TCP, proprietary protocols, HTTP, WebSockets. It remains painful, slow, hard to scale, and essentially centralized. Distributed P2P architectures are mostly for play, not work. How many applications use Skype or Bittorrent to exchange data?
Which brings us back to the science of programming. To fix the world, we needed to do two things. One, to solve the general problem of "how to connect any code to any code, anywhere". Two, to wrap that up in the simplest possible building blocks that people could understand and use easily.
It sounds ridiculously simple. And maybe it is. That's kind of the whole point.
ØMQ in a Hundred Words
|top prev next
ØMQ (ZeroMQ, 0MQ, zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry whole messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N-to-N with patterns like fanout, pub-sub, task distribution, and request-reply. It's fast enough to be the fabric for clustered products. Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. It has a score of language APIs and runs on most operating systems. ØMQ is from iMatix and is LGPL open source.
Some Assumptions
|top prev next
We assume you are using the latest stable release of ØMQ. We assume you are using a Linux box or something similar. We assume you can read C code, more or less, that's the default language for the examples. We assume that when we write constants like PUSH or SUBSCRIBE you can imagine they are really called ZMQ_PUSH or ZMQ_SUBSCRIBE if the programming language needs it.
Getting the Examples
|top prev next
The Guide examples live in the Guide's git repository. The simplest way to get all the examples is to clone this repository:
git clone --depth=1 git://github.com/imatix/zguide.git
And then browse the examples subdirectory. You'll find examples by language. If there are examples missing in a language you use, you're encouraged to submit a translation. This is how the Guide became so useful, thanks to the work of many people.
All examples are licensed under MIT/X11, unless otherwise specified in the source code.
Ask and Ye Shall Receive
|top prev next
So let's start with some code. We start of course with a Hello World example. We'll make a client and a server. The client sends "Hello" to the server, which replies with "World". Here's the server in C, which opens a ØMQ socket on port 5555, reads requests on it, and replies with "World" to each request:
// Hello World server
#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main (void)
// Socket to talk to clients
void *context = zmq_ctx_new ();
void *responder = zmq_socket (context, ZMQ_REP);
int rc = zmq_bind (responder, "tcp://*:5555");
assert (rc == 0);
while (1) {
char buffer [10];
zmq_recv (responder, buffer, 10, 0);
printf ("Received Hello\n");
sleep (1); // Do some 'work'
zmq_send (responder, "World", 5, 0);
return 0;
hwserver.c: Hello World server
Figure 1 - Request-Reply
The REQ-REP socket pair is lockstep. The client does zmq_send(3) and then zmq_recv(3), in a loop (or once if that's all it needs). Doing any other sequence (e.g. sending two messages in a row) will result in a return code of -1 from the send or recv call. Similarly the service does zmq_recv(3) and then zmq_send(3) in that order, and as often as it needs to.
ØMQ uses C as its reference language and this is the main language we'll use for examples. If you're reading this on-line, the link below the example takes you to translations into other programming languages. Let's compare the same server in C++:
// Hello World server in C++
// Binds REP socket to tcp://*:5555
// Expects "Hello" from client, replies with "World"
#include <zmq.hpp>
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#include <windows.h>
#define sleep(n) Sleep(n)
int main () {
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
std::cout << "Received Hello" << std::endl;
// Do some 'work'
// Send reply back to client
zmq::message_t reply (5);
memcpy (reply.data (), "World", 5);
socket.send (reply);
return 0;
hwserver.cpp: Hello World server
You can see that the ØMQ API is similar in C and C++. In a language like PHP, we can hide even more and the code becomes even easier to read:
* Hello World server
* Binds REP socket to tcp://*:5555
* Expects "Hello" from client, replies with "World"
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
$context = new ZMQContext(1);
// Socket to talk to clients
$responder = new ZMQSocket($context, ZMQ::SOCKET_REP);
while (true) {
// Wait for next request from client
$request = $responder->recv();
printf ("Received request: [%s]\n", $request);
// Do some 'work'
sleep (1);
// Send reply back to client
hwserver.php: Hello World server
Here's the client code (click the link below the source to look at, or contribute a translation in your favorite programming language):
* Hello World client
* Connects REQ socket to tcp://localhost:5555
* Sends "Hello" to server, expects "World" back
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
$context = new ZMQContext();
// Socket to talk to server
echo "Connecting to hello world server…\n";
$requester = new ZMQSocket($context, ZMQ::SOCKET_REQ);
for ($request_nbr = 0; $request_nbr != 10; $request_nbr++) {
printf ("Sending request %d…\n", $request_nbr);
$reply = $requester->recv();
printf ("Received reply %d: [%s]\n", $request_nbr, $reply);
hwclient.php: Hello World client
Now this looks too simple to be realistic, but a ØMQ socket is what you get when you take a normal TCP socket, inject it with a mix of radioactive isotopes stolen from a secret Soviet atomic research project, bombard it with 1950-era cosmic rays, and put it into the hands of a drug-addled comic book author with a badly-disguised fetish for bulging muscles clad in spandex. Yes, ØMQ sockets are the world-saving superheroes of the networking world.
Figure 2 - A terrible accident…
You could literally throw thousands of clients at this server, all at once, and it would continue to work happily and quickly. For fun, try starting the client and then starting the server, see how it all still works, then think for a second what this means.
Let me explain briefly what these two programs are actually doing. They create a ØMQ context to work with, and a socket. Don't worry what the words mean. You'll pick it up. The server binds its REP (reply) socket to port 5555. The server waits for a request, in a loop, and responds each time with a reply. The client sends a request and reads the reply back from the server.
If you kill the server (Ctrl-C) and restart it, the client won't recover properly. Recovering from crashing processes isn't quite that easy. Making a reliable request-reply flow is complex enough that I won't cover it until Chapter Four.
There is a lot happening behind the scenes but what matters to us programmers is how short and sweet the code is, and how often it doesn't crash, even under heavy load. This is the request-reply pattern, probably the simplest way to use ØMQ. It maps to RPC and the classic client-server model.
A Minor Note on Strings
|top prev next
ØMQ doesn't know anything about the data you send except its size in bytes. That means you are responsible for formatting it safely so that applications can read it back. Doing this for objects and complex data types is a job for specialized libraries like Protocol Buffers. But even for strings you need to take care.
In C and some other languages, strings are terminated with a null byte. We could send a string like "HELLO" with that extra null byte:
zmq_send (requester, "Hello", 6, 0);
However if you send a string from another language it probably will not include that null byte. For example, when we send that same string in Python, we do this:
socket.send ("Hello")
Then what goes onto the wire is a length (one byte for shorter strings) and the string contents, as individual characters.
Figure 3 - A ØMQ string
And if you read this from a C program, you will get something that looks like a string, and might by accident act like a string (if by luck the five bytes find themselves followed by an innocently lurking null), but isn't a proper string. Which means that your client and server don't agree on the string format, you will get weird results.
When you receive string data from ØMQ, in C, you simply cannot trust that it's safely terminated. Every single time you read a string you should allocate a new buffer with space for an extra byte, copy the string, and terminate it properly with a null.
So let's establish the rule that ØMQ strings are length-specified, and are sent on the wire without a trailing null. In the simplest case (and we'll do this in our examples) a ØMQ string maps neatly to a ØMQ message frame, which looks like the above figure, a length and some bytes.
Here is what we need to do, in C, to receive a ØMQ string and deliver it to the application as a valid C string:
// Receive ZeroMQ string from socket and convert into C string
// Chops string at 255 chars, if it's longer
static char *
s_recv (void *socket) {
char buffer [256];
int size = zmq_recv (socket, buffer, 255, 0);
if (size == -1)
return NULL;
if (size > 255)
size = 255;
buffer [size] = \0;
/* use strndup(buffer, sizeof(buffer)-1) in *nix */
return strdup (buffer);
This makes a very handy helper function and in the spirit of making things we can reuse profitably, let's write a similar 's_send' function that sends strings in the correct ØMQ format, and package this into a header file we can reuse.
The result is zhelpers.h, which lets us write sweeter and shorter ØMQ applications in C. It is a fairly long source, and only fun for C developers, so read it at leisure.
Version Reporting
|top prev next
ØMQ does come in several versions and quite often, if you hit a problem, it'll be something that's been fixed in a later version. So it's a useful trick to know exactly what version of ØMQ you're actually linking with. Here is a tiny program that does that:
/* Report 0MQ version
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
if (class_exists("ZMQ") && defined("ZMQ::LIBZMQ_VER")) {
echo ZMQ::LIBZMQ_VER, PHP_EOL;
version.php: ØMQ version reporting
Getting the Message Out
|top prev next
The second classic pattern is one-way data distribution, in which a server pushes updates to a set of clients. Let's see an example that pushes out weather updates consisting of a zip code, temperature, and relative humidity. We'll generate random values, just like the real weather stations do.
Here's the server. We'll use port 5556 for this application:
* Weather update server
* Binds PUB socket to tcp://*:5556
* Publishes random weather updates
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
// Prepare our context and publisher
$context = new ZMQContext();
$publisher = $context->getSocket(ZMQ::SOCKET_PUB);
while (true) {
// Get values that will fool the boss
$zipcode = mt_rand(0, 100000);
$temperature = mt_rand(-80, 135);
$relhumidity = mt_rand(10, 60);
// Send message to all subscribers
$update = sprintf ("%05d %d %d", $zipcode, $temperature, $relhumidity);
wuserver.php: Weather update server
There's no start, and no end to this stream of updates, it's like a never ending broadcast.
Figure 4 - Publish-Subscribe
Here is client application, which listens to the stream of updates and grabs anything to do with a specified zip code, by default New York City because that's a great place to start any adventure:
* Weather update client
* Connects SUB socket to tcp://localhost:5556
* Collects weather updates and finds avg temp in zipcode
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
$context = new ZMQContext();
// Socket to talk to server
echo "Collecting updates from weather server…", PHP_EOL;
$subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB);
// Subscribe to zipcode, default is NYC, 10001
$filter = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : "10001";
$subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter);
// Process 100 updates
$total_temp = 0;
for ($update_nbr = 0; $update_nbr < 100; $update_nbr++) {
$string = $subscriber->recv();
sscanf ($string, "%d %d %d", $zipcode, $temperature, $relhumidity);
$total_temp += $temperature;
printf ("Average temperature for zipcode '%s' was %dF\n",
$filter, (int) ($total_temp / $update_nbr));
wuclient.php: Weather update client
Note that when you use a SUB socket you must set a subscription using zmq_setsockopt(3) and SUBSCRIBE, as in this code. If you don't set any subscription, you won't get any messages. It's a common mistake for beginners. The subscriber can set many subscriptions, which are added together. That is, if a update matches ANY subscription, the subscriber receives it. The subscriber can also unsubscribe specific subscriptions. Subscriptions are length-specified blobs. See zmq_setsockopt(3) for how this works.
The PUB-SUB socket pair is asynchronous. The client does zmq_recv(3), in a loop (or once if that's all it needs). Trying to send a message to a SUB socket will cause an error. Similarly the service does zmq_send(3) as often as it needs to, but must not do zmq_recv(3) on a PUB socket.
In theory with ØMQ sockets, it does not matter which end connects, and which end binds. However with PUB-SUB sockets, if you bind the SUB socket and connect the PUB socket, the SUB socket may receive old messages, i.e. messages sent before the SUB started up. This is an artifact of the way bind/connect works. It's best to bind the PUB and connect the SUB, if you can.
There is one more important thing to know about PUB-SUB sockets: you do not know precisely when a subscriber starts to get messages. Even if you start a subscriber, wait a while, and then start the publisher, the subscriber will always miss the first messages that the publisher sends. This is because as the subscriber connects to the publisher (something that takes a small but non-zero time), the publisher may already be sending messages out.
This "slow joiner" symptom hits enough people, often enough, that I'm going to explain it in detail. Remember that ØMQ does asynchronous I/O, i.e. in the background. Say you have two nodes doing this, in this order:
- Subscriber connects to an endpoint and receives and counts messages.
- Publisher binds to an endpoint and immediately sends 1,000 messages.
Then the subscriber will most likely not receive anything. You'll blink, check that you set a correct filter, and try again, and the subscriber will still not receive anything.
Making a TCP connection involves to and fro handshaking that takes several milliseconds depending on your network and the number of hops between peers. In that time, ØMQ can send very many messages. For sake of argument assume it takes 5 msecs to establish a connection, and that same link can handle 1M messages per second. During the 5 msecs that the subscriber is connecting to the publisher, it takes the publisher only 1 msec to send out those 1K messages.
In Chapter Two I'll explain how to synchronize a publisher and subscribers so that you don't start to publish data until the subscriber(s) really are connected and ready. There is a simple and stupid way to delay the publisher, which is to sleep. I'd never do this in a real application though, it is extremely fragile as well as inelegant and slow. Use sleeps to prove to yourself what's happening, and then wait for Chapter 2 to see how to do this right.
The alternative to synchronization is to simply assume that the published data stream is infinite and has no start, and no end. This is how we built our weather client example.
So the client subscribes to its chosen zip code and collects a thousand updates for that zip code. That means about ten million updates from the server, if zip codes are randomly distributed. You can start the client, and then the server, and the client will keep working. You can stop and restart the server as often as you like, and the client will keep working. When the client has collected its thousand updates, it calculates the average, prints it, and exits.
Some points about the publish-subscribe pattern:
- A subscriber can in fact connect to more than one publisher, using one 'connect' call each time. Data will then arrive and be interleaved so that no single publisher drowns out the others.
- If a publisher has no connected subscribers, then it will simply drop all messages.
- If you're using TCP, and a subscriber is slow, messages will queue up on the publisher. We'll look at how to protect publishers against this, using the "high-water mark" later.
- In the current versions of ØMQ, filtering happens at the subscriber side, not the publisher side. This means, over TCP, that a publisher will send all messages to all subscribers, which will then drop messages they don't want.
This is how long it takes to receive and filter 10M messages on my box, which is an Intel 4 core Q8300, fast but nothing special:
ph@ws200901:~/work/git/ØMQGuide/examples/c$ time wuclient
Collecting updates from weather server...
Average temperature for zipcode '10001 ' was 18F
real 0m5.939s
user 0m1.590s
sys 0m2.290s
Divide and Conquer
|top prev next
As a final example (you are surely getting tired of juicy code and want to delve back into philological discussions about comparative abstractive norms), let's do a little supercomputing. Then coffee. Our supercomputing application is a fairly typical parallel processing model:
- We have a ventilator that produces tasks that can be done in parallel.
- We have a set of workers that process tasks.
- We have a sink that collects results back from the worker processes.
In reality, workers run on superfast boxes, perhaps using GPUs (graphic processing units) to do the hard maths. Here is the ventilator. It generates 100 tasks, each is a message telling the worker to sleep for some number of milliseconds:
* Task ventilator
* Binds PUSH socket to tcp://localhost:5557
* Sends batch of tasks to workers via that socket
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
$context = new ZMQContext();
// Socket to send messages on
$sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
echo "Press Enter when the workers are ready: ";
$fp = fopen('php://stdin', 'r');
$line = fgets($fp, 512);
echo "Sending tasks to workers…", PHP_EOL;
// The first message is "0" and signals start of batch
// Send 100 tasks
$total_msec = 0; // Total expected cost in msecs
for ($task_nbr = 0; $task_nbr < 100; $task_nbr++) {
// Random workload from 1 to 100msecs
$workload = mt_rand(1, 100);
$total_msec += $workload;
printf ("Total expected cost: %d msec\n", $total_msec);
sleep (1); // Give 0MQ time to deliver
taskvent.php: Parallel task ventilator
Figure 5 - Parallel Pipeline
Here is the worker application. It receives a message, sleeps for that number of seconds, then signals that it's finished:
* Task worker
* Connects PULL socket to tcp://localhost:5557
* Collects workloads from ventilator via that socket
* Connects PUSH socket to tcp://localhost:5558
* Sends results to sink via that socket
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
$context = new ZMQContext();
// Socket to receive messages on
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
// Socket to send messages to
$sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
// Process tasks forever
while (true) {
$string = $receiver->recv();
// Simple progress indicator for the viewer
echo $string, PHP_EOL;
// Do the work
usleep($string * 1000);
// Send results to sink
taskwork.php: Parallel task worker
Here is the sink application. It collects the 100 tasks, then calculates how long the overall processing took, so we can confirm that the workers really were running in parallel, if there are more than one of them:
* Task sink
* Binds PULL socket to tcp://localhost:5558
* Collects results from workers via that socket
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
// Prepare our context and socket
$context = new ZMQContext();
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
// Wait for start of batch
$string = $receiver->recv();
// Start our clock now
$tstart = microtime(true);
// Process 100 confirmations
$total_msec = 0; // Total calculated cost in msecs
for ($task_nbr = 0; $task_nbr < 100; $task_nbr++) {
$string = $receiver->recv();
if ($task_nbr % 10 == 0) {
echo ":";
} else {
echo ".";
$tend = microtime(true);
$total_msec = ($tend - $tstart) * 1000;
echo PHP_EOL;
printf ("Total elapsed time: %d msec", $total_msec);
echo PHP_EOL;
tasksink.php: Parallel task sink
The average cost of a batch is 5 seconds. When we start 1, 2, 4 workers we get results like this from the sink:
# 1 worker
Total elapsed time: 5034 msec
# 2 workers
Total elapsed time: 2421 msec
# 4 workers
Total elapsed time: 1018 msec
Let's look at some aspects of this code in more detail:
- The workers connect upstream to the ventilator, and downstream to the sink. This means you can add workers arbitrarily. If the workers bound to their endpoints, you would need (a) more endpoints and (b) to modify the ventilator and/or the sink each time you added a worker. We say that the ventilator and sink are 'stable' parts of our architecture and the workers are 'dynamic' parts of it.
- We have to synchronize the start of the batch with all workers being up and running. This is a fairly common gotcha in ØMQ and there is no easy solution. The 'connect' method takes a certain time. So when a set of workers connect to the ventilator, the first one to successfully connect will get a whole load of messages in that short time while the others are also connecting. If you don't synchronize the start of the batch somehow, the system won't run in parallel at all. Try removing the wait, and see.
- The ventilator's PUSH socket distributes tasks to workers (assuming they are all connected before the batch starts going out) evenly. This is called load-balancing and it's something we'll look at again in more detail.
- The sink's PULL socket collects results from workers evenly. This is called fair-queuing.
Figure 6 - Fair Queuing
The pipeline pattern also exhibits the "slow joiner" syndrome, leading to accusations that PUSH sockets don't load balance properly. If you are using PUSH and PULL, and one of your workers gets way more messages than the others, it's because that PULL socket has joined faster than the others, and grabs a lot of messages before the others manage to connect.
Programming with ØMQ
|top prev next
Having seen some examples, you're eager to start using ØMQ in some apps. Before you start that, take a deep breath, chillax, and reflect on some basic advice that will save you stress and confusion.
- Learn ØMQ step by step. It's just one simple API but it hides a world of possibilities. Take the possibilities slowly, master each one.
- Write nice code. Ugly code hides problems and makes it hard for others to help you. You might get used to meaningless variable names, but people reading your code won't. Use names that are real words, that say something other than "I'm too careless to tell you what this variable is really for". Use consistent indentation, clean layout. Write nice code and your world will be more comfortable.
- Test what you make as you make it. When your program doesn't work, you should know what five lines are to blame. This is especially true when you do ØMQ magic, which just won't work the first few times you try it.
- When you find that things don't work as expected, break your code into pieces, test each one, see which one is not working. ØMQ lets you make essentially modular code, use that to your advantage.
- Make abstractions (classes, methods, whatever) as you need them. If you copy/paste a lot of code you're going to copy/paste errors too.
To illustrate, here is a fragment of code someone asked me to help fix:
// NOTE: do NOT reuse this example code!
static char *topic_str = "msg.x|";
void* pub_worker(void* arg){
void *ctx = arg;
void *qskt = zmq_socket(ctx, ZMQ_REP);
int rc = zmq_connect(qskt, "inproc://querys");
assert(rc == 0);
void *pubskt = zmq_socket(ctx, ZMQ_PUB);
rc = zmq_bind(pubskt, "inproc://publish");
assert(rc == 0);
uint8_t cmd;
uint32_t nb;
zmq_msg_t topic_msg, cmd_msg, nb_msg, resp_msg;
zmq_msg_init_data(&topic_msg, topic_str, strlen(topic_str) , NULL, NULL);
fprintf(stdout,"WORKER: ready to receive messages\n");
// NOTE: do NOT reuse this example code, It's broken.
// e.g. topic_msg will be invalid the second time through
while (1){
zmq_send(pubskt, &topic_msg, ZMQ_SNDMORE);
zmq_recv(qskt, &cmd_msg, 0);
memcpy(&cmd, zmq_msg_data(&cmd_msg), sizeof(uint8_t));
zmq_send(pubskt, &cmd_msg, ZMQ_SNDMORE);
fprintf(stdout, "received cmd %u\n", cmd);
zmq_recv(qskt, &nb_msg, 0);
memcpy(&nb, zmq_msg_data(&nb_msg), sizeof(uint32_t));
zmq_send(pubskt, &nb_msg, 0);
fprintf(stdout, "received nb %u\n", nb);
zmq_msg_init_size(&resp_msg, sizeof(uint8_t));
memset(zmq_msg_data(&resp_msg), 0, sizeof(uint8_t));
zmq_send(qskt, &resp_msg, 0);
return NULL;
This is what I rewrote it to, as part of finding the bug:
// NOTE: do NOT reuse this example code!
static char *topic_str = "msg.x|";
void* pub_worker(void* arg){
void *ctx = arg;
void *qskt = zmq_socket(ctx, ZMQ_REP);
int rc = zmq_connect(qskt, "inproc://querys");
assert(rc == 0);
void *pubskt = zmq_socket(ctx, ZMQ_PUB);
rc = zmq_bind(pubskt, "inproc://publish");
assert(rc == 0);
uint8_t cmd;
uint32_t nb;
zmq_msg_t topic_msg, cmd_msg, nb_msg, resp_msg;
zmq_msg_init_data(&topic_msg, topic_str, strlen(topic_str) , NULL, NULL);
fprintf(stdout,"WORKER: ready to receive messages\n");
// NOTE: do NOT reuse this example code, It's broken.
// e.g. topic_msg will be invalid the second time through
while (1){
zmq_msg_send(pubskt, &topic_msg, ZMQ_SNDMORE);
zmq_msg_recv(qskt, &cmd_msg, 0);
memcpy(&cmd, zmq_msg_data(&cmd_msg), sizeof(uint8_t));
zmq_msg_send(pubskt, &cmd_msg, ZMQ_SNDMORE);
fprintf(stdout, "received cmd %u\n", cmd);
zmq_msg_recv(qskt, &nb_msg, 0);
memcpy(&nb, zmq_msg_data(&nb_msg), sizeof(uint32_t));
zmq_msg_send(pubskt, &nb_msg, 0);
fprintf(stdout, "received nb %u\n", nb);
zmq_msg_init_size(&resp_msg, sizeof(uint8_t));
memset(zmq_msg_data(&resp_msg), 0, sizeof(uint8_t));
zmq_msg_send(qskt, &resp_msg, 0);
return NULL;
In the end, the problem was that the application was passing sockets between threads, which crashed weirdly. It became legal behavior in ØMQ/2.1, but remains dangerous unless you use a "full memory barrier", and it's something we advise against doing.
Getting the Context Right
|top prev next
ØMQ applications always start by creating a context, and then using that for creating sockets. In C, it's the zmq_init(3) call. You should create and use exactly one context in your process. Technically, the context is the container for all sockets in a single process, and acts as the transport for inproc sockets, which are the fastest way to connect threads in one process. If at runtime a process has two contexts, these are like separate ØMQ instances. If that's explicitly what you want, OK, but otherwise remember:
Do one zmq_init(3) at the start of your main line code, and one zmq_term(3) at the end.
If you're using the fork() system call, each process needs its own context. If you do zmq_init(3) in the main process before calling fork(), the child processes get their own contexts. In general you want to do the interesting stuff in the child processes, and just manage these from the parent process.
Making a Clean Exit
|top prev next
Classy programmers share the same motto as classy hit men: always clean-up when you finish the job. When you use ØMQ in a language like Python, stuff gets automatically freed for you. But when using C you have to carefully free objects when you're finished with them, or you get memory leaks, unstable applications, and generally bad karma.
Memory leaks are one thing, but ØMQ is quite finicky about how you exit an application. The reasons are technical and painful but the upshot is that if you leave any sockets open, the zmq_term(3) function will hang forever. And even if you close all sockets, zmq_term(3) will by default wait forever if there are pending connects or sends. Unless you set the LINGER to zero on those sockets before closing them.
The ØMQ objects we need to worry about are messages, sockets, and contexts. Luckily it's quite simple, at least in simple programs:
- Always close a message the moment you are done with it, using zmq_msg_close(3).
- If you are opening and closing a lot of sockets, that's probably a sign you need to redesign your application.
- When you exit the program, close your sockets and then call zmq_term(3). This destroys the context.
If you're doing multithreaded work, it gets rather more complex than this. We'll get to multithreading in the next chapter, but because some of you will, despite warnings, will try to run before you can safely walk, below is the quick and dirty guide to making a clean exit in a multithreaded ØMQ application.
First, do not try to use the same socket from multiple threads. No, don't explain why you think this would be excellent fun, just please don't do it. Next, relingerfy and close all sockets, and terminate the context in the main thread. Lastly, this'll cause any blocking receives or polls or sends in attached threads (i.e. which share the same context) to return with an error. Catch that, and then relingerize and close sockets in that thread, and exit. Do not terminate the same context twice. The zmq_term in the main thread will block until all sockets it knows about are safely closed.
Voila! It's complex and painful enough that any language binding author worth his or her salt will do this automatically and make the socket closing dance unnecessary.
Why We Needed ØMQ
|top prev next
Now that you've seen ØMQ in action, let's go back to the "why".
Many applications these days consist of components that stretch across some kind of network, either a LAN or the Internet. So many application developers end up doing some kind of messaging. Some developers use message queuing products, but most of the time they do it themselves, using TCP or UDP. These protocols are not hard to use, but there is a great difference between sending a few bytes from A to B, and doing messaging in any kind of reliable way.
Let's look at the typical problems we face when we start to connect pieces using raw TCP. Any reusable messaging layer would need to solve all or most these:
- How do we handle I/O? Does our application block, or do we handle I/O in the background? This is a key design decision. Blocking I/O creates architectures that do not scale well. But background I/O can be very hard to do right.
- How do we handle dynamic components, i.e. pieces that go away temporarily? Do we formally split components into "clients" and "servers" and mandate that servers cannot disappear? What then if we want to connect servers to servers? Do we try to reconnect every few seconds?
- How do we represent a message on the wire? How do we frame data so it's easy to write and read, safe from buffer overflows, efficient for small messages, yet adequate for the very largest videos of dancing cats wearing party hats?
- How do we handle messages that we can't deliver immediately? Particularly, if we're waiting for a component to come back on-line? Do we discard messages, put them into a database, or into a memory queue?
- Where do we store message queues? What happens if the component reading from a queue is very slow, and causes our queues to build up? What's our strategy then?
- How do we handle lost messages? Do we wait for fresh data, request a resend, or do we build some kind of reliability layer that ensures messages cannot be lost? What if that layer itself crashes?
- What if we need to use a different network transport. Say, multicast instead of TCP unicast? Or IPv6? Do we need to rewrite the applications, or is the transport abstracted in some layer?
- How do we route messages? Can we send the same message to multiple peers? Can we send replies back to an original requester?
- How do we write an API for another language? Do we re-implement a wire-level protocol or do we repackage a library? If the former, how can we guarantee efficient and stable stacks? If the latter, how can we guarantee interoperability?
- How do we represent data so that it can be read between different architectures? Do we enforce a particular encoding for data types? How far is this the job of the messaging system rather than a higher layer?
- How do we handle network errors? Do we wait and retry, ignore them silently, or abort?
Take a typical open source project like Hadoop Zookeeper and read the C API code in src/c/src/zookeeper.c. It's 3,200 lines of mystery and in there is an undocumented, client-server network communication protocol. I see it's efficient because it uses poll() instead of select(). But really, Zookeeper should be using a generic messaging layer and an explicitly documented wire level protocol. It is incredibly wasteful for teams to be building this particular wheel over and over.
Figure 7 - Messaging as it Starts
But how to make a reusable messaging layer? Why, when so many projects need this technology, are people still doing it the hard way, by driving TCP sockets in their code, and solving the problems in that long list, over and over?
It turns out that building reusable messaging systems is really difficult, which is why few FOSS projects ever tried, and why commercial messaging products are complex, expensive, inflexible, and brittle. In 2006 iMatix designed AMQP which started to give FOSS developers perhaps the first reusable recipe for a messaging system. AMQP works better than many other designs but remains relatively complex, expensive, and brittle. It takes weeks to learn to use, and months to create stable architectures that don't crash when things get hairy.
Most messaging projects, like AMQP, that try to solve this long list of problems in a reusable way do so by inventing a new concept, the "broker", that does addressing, routing, and queuing. This results in a client-server protocol or a set of APIs on top of some undocumented protocol, that let applications speak to this broker. Brokers are an excellent thing in reducing the complexity of large networks. But adding broker-based messaging to a product like Zookeeper would make it worse, not better. It would mean adding an additional big box, and a new single point of failure. A broker rapidly becomes a bottleneck and a new risk to manage. If the software supports it, we can add a second, third, fourth broker and make some fail-over scheme. People do this. It creates more moving pieces, more complexity, more things to break.
And a broker-centric set-up needs its own operations team. You literally need to watch the brokers day and night, and beat them with a stick when they start misbehaving. You need boxes, and you need backup boxes, and you need people to manage those boxes. It is only worth doing for large applications with many moving pieces, built by several teams of people, over several years.
So small to medium application developers are trapped. Either they avoid network programming, and make monolithic applications that do not scale. Or they jump into network programming and make brittle, complex applications that are hard to maintain. Or they bet on a messaging product, and end up with scalable applications that depend on expensive, easily broken technology. There has been no really good choice, which is maybe why messaging is largely stuck in the last century and stirs strong emotions. Negative ones for users, gleeful joy for those selling support and licenses.
Figure 8 - Messaging as it Becomes
What we need is something that does the job of messaging but does it in such a simple and cheap way that it can work in any application, with close to zero cost. It should be a library that you just link with, without any other dependencies. No additional moving pieces, so no additional risk. It should run on any OS and work with any programming language.
And this is ØMQ: an efficient, embeddable library that solves most of the problems an application needs to become nicely elastic across a network, without much cost.
- It handles I/O asynchronously, in background threads. These communicate with application threads using lock-free data structures, so ØMQ applications need no locks, semaphores, or other wait states.
- Components can come and go dynamically and ØMQ will automatically reconnect. This means you can start components in any order. You can create "service-oriented architectures" (SOAs) where services can join and leave the network at any time.
- It queues messages automatically when needed. It does this intelligently, pushing messages as close as possible to the receiver before queuing them.
- It has ways of dealing with over-full queues (called "high water mark"). When a queue is full, ØMQ automatically blocks senders, or throws away messages, depending on the kind of messaging you are doing (the so-called "pattern").
- It lets your applications talk to each other over arbitrary transports: TCP, multicast, in-process, inter-process. You don't need to change your code to use a different transport.
- It handles slow/blocked readers safely, using different strategies that depend on the messaging pattern.
- It lets you route messages using a variety of patterns such as request-reply and publish-subscribe. These patterns are how you create the topology, the structure of your network.
- It lets you place pattern-extending "devices" (small brokers) in the network when you need to reduce the complexity of interconnecting many pieces.
- It delivers whole messages exactly as they were sent, using a simple framing on the wire. If you write a 10k message, you will receive a 10k message.
- It does not impose any format on messages. They are blobs of zero to gigabytes large. When you want to represent data you choose some other product on top, such as Google's protocol buffers, XDR, and others.
- It handles network errors intelligently. Sometimes it retries, sometimes it tells you an operation failed.
- It reduces your carbon footprint. Doing more with less CPU means your boxes use less power, and you can keep your old boxes in use for longer. Al Gore would love ØMQ.
Actually ØMQ does rather more than this. It has a subversive effect on how you develop network-capable applications. Superficially it's just a socket API on which you do zmq_recv(3) and zmq_send(3). But message processing rapidly becomes the central loop, and your application soon breaks down into a set of message processing tasks. It is elegant and natural. And it scales: each of these tasks maps to a node, and the nodes talk to each other across arbitrary transports. Two nodes in one process (node is a thread), two nodes on one box (node is a process), two boxes on one network (node is a box). With no application code changes.
Socket Scalability
|top prev next
Let's see ØMQ's scalability in action. Here is a shell script that starts the weather server and then a bunch of clients in parallel:
wuserver &
wuclient 12345 &
wuclient 23456 &
wuclient 34567 &
wuclient 45678 &
wuclient 56789 &
As the clients run, we take a look at the active processes using 'top', and we see something like (on a 4-core box):
7136 ph 20 0 1040m 959m 1156 R 157 12.0 16:25.47 wuserver
7966 ph 20 0 98608 1804 1372 S 33 0.0 0:03.94 wuclient
7963 ph 20 0 33116 1748 1372 S 14 0.0 0:00.76 wuclient
7965 ph 20 0 33116 1784 1372 S 6 0.0 0:00.47 wuclient
7964 ph 20 0 33116 1788 1372 S 5 0.0 0:00.25 wuclient
7967 ph 20 0 33072 1740 1372 S 5 0.0 0:00.35 wuclient
Let's think for a second about what is happening here. The weather server has a single socket, and yet here we have it sending data to five clients in parallel. We could have thousands of concurrent clients. The server application doesn't see them, doesn't talk to them directly.
Missing Message Problem Solver
|top prev next
As you start to program with ØMQ you will come across one problem more than once: you lose messages that you expect to receive. Here is a basic problem solver that walks through the most common causes for this. Don't worry if some of the terminology is unfamiliar still, it'll become clearer in the next chapters.
Figure 9 - Missing Message Problem Solver
If you're using ØMQ in a context where failures are expensive, then you want to plan properly. First, build prototypes that let you learn and test the different aspects of your design. Stress them until they break, so that you know exactly how strong your designs are. Second, invest in testing. This means building test frameworks, ensuring you have access to realistic setups with sufficient computer power, and getting time or help to actually test seriously. Ideally, one team writes the code, a second team tries to break it. Lastly, do get your organization to contact iMatix to discuss how we can help to make sure things work properly, and can be fixed rapidly if they break.
In short: if you have not proven an architecture works in realistic conditions, it will most likely break at the worst possible moment.
Warning - Unstable Paradigms!
|top prev next
Traditional network programming is built on the general assumption that one socket talks to one connection, one peer. There are multicast protocols but they are exotic. When we assume "one socket = one connection", we scale our architectures in certain ways. We create threads of logic where each thread work with one socket, one peer. We place intelligence and state in these threads.
In the ØMQ universe, sockets are clever multithreaded applications that manage a whole set of connections automagically for you. You can't see, work with, open, close, or attach state to these connections. Whether you use blocking send or receive, or poll, all you can talk to is the socket, not the connections it manages for you. The connections are private and invisible, and this is the key to ØMQ's scalability.
Because your code, talking to a socket, can then handle any number of connections across whatever network protocols are around, without change. A messaging pattern sitting in ØMQ can scale more cheaply than a messaging pattern sitting in your application code.
So the general assumption no longer applies. As you read the code examples, your brain will try to map them to what you know. You will read "socket" and think "ah, that represents a connection to another node". That is wrong. You will read "thread" and your brain will again think, "ah, a thread represents a connection to another node", and again your brain will be wrong.
If you're reading this Guide for the first time, realize that until you actually write ØMQ code for a day or two (and maybe three or four days), you may feel confused, especially by how simple ØMQ makes things for you, and you may try to impose that general assumption on ØMQ, and it won't work. And then you will experience your moment of enlightenment and trust, that zap-pow-kaboom satori paradigm-shift moment when it all becomes clear.


text:
In June I had a chance to visit Vancouver's famous night market, a summertime tradition the Chinese-Canadian community has imported from Hong Kong. There you can buy everything from crispy "potato tornados" and bubble drinks, to incredible handmade t-shirts. And the coolest shirts I saw were from local t-shirt designer Thinkhead. Lucky for you, Thinkhead creator Peter has now put some of his wares online. Check out the mania.
Here are some of the nerdy and satisfyingly inexplicable designs from Thinkhead - there are even more where these came from, so hopefully Peter will get those up on his site soon. For now, you can pick one up for $25 Canadian on the Thinkhead site.
Food for thought. Because of course you always wanted your brain to look like a Pac Man.
Steal chicken. This mysterious and wonderful shirt could mean almost anything. "Is he sneaking around and actually stealing a chicken?" I asked Peter. "Yeah," he said. "And he's feeling a little bad about it." I suppose you could also read this as an exhortation, like "go steal a chicken." No matter how you interpret it, this is one cute chunk of weirdness for your chest.
Think outside the box. Or, this is your brain on arrows.
Smart pocket. Love this variation on the nerd pocket tee.
You can learn more, and buy these tees, at Thinkhead.


text:
NEWS- Porc-quoi? Officials ask USDA for answers
Both Senator George Allen and U.S. Representative Virgil Goode have asked the U.S. Department of Agriculture for an explanation of the events that occurred September 12 in a predawn raid in Buckingham County. But contrary to what the Hook reported in its October 5 "Boar war" cover story, a USDA spokesman says the agency is not conducting an internal investigation of its handling of the slaughter of 79 Russian boars at the Willis River hunting preserve.
On the morning of the raid, game wardens arrested former cop/bow-hunting pro Danny Henshaw on misdemeanor charges of having an illegal hunting enclosure, a business he had openly run and advertised for 16 years.
The Russian wild boars in his preserve were simultaneously quarantined and killed– and then tested for pseudorabies, a highly contagious swine disease that does not affect humans. Critics have criticized the government operation as "heavy handed," and some are planning a public protest.
The Office of the Inspector General, which investigates internal affairs for the USDA, "has no involvement or investigation regarding this incident," says USDA-OIG deputy counsel Paul Feeney.
USDA agents were working for the Virginia Department of Agriculture and Consumer Services when they conducted the drug bust-like raid, which included the slaughter of "Cupid" and "Valentine," pet pigs Cindi Henshaw had raised from birth and kept in a separate enclosure from the hunting preserve boars.
"I am very saddened by your situation, especially by the loss of your pet pigs," Congressman Goode wrote to Henshaw. "If no tests were run on these pet pigs, I would like to know why tests were not needed," Goode wrote in a separate letter to the USDA.
State and federal agents set up camp for 11 days at Willis River, left pools of blood at the 100-acre preserve, and hauled off the boars in open stock trailers, according to the Henshaws.
The incident has sparked outrage among citizens already dubious of USDA handling of contagious diseases. The Granny Warriors, a group concerned with the rights of animal owners, is staging a protest October 24 at USDA offices in Richmond.
According to information received by Cindi Henshaw, of the 79 hogs killed, 42 were tested for pseudorabies, and 15 came back positive.However, the couple were not allowed to take their own blood samples from their pigs. "I do not believe for one second that our pigs were diseased," maintains Cindi Henshaw.
Danny and Cindi Henshaw mourn the loss of their pet pigs, Cupid and Valentine, at the pen where they were shot.


text:
Posts Tagged 'MINI Cooper S'
MiniPhilippines Introduces the New MINI by MINI Philippines
Now, that's a lot of minis!
Friends in the digital media world kid me aside that I should sell my MiniPhilippines domain name to MINI Philippines, even just for an entry-level MINI which costs only P2.1 million. I quipped I'd be happy with that. Who knows?
But that's not the story here. It's about MINI Cooper, the car.
The Philippine Bloggers Network was invited to an early announcement of "The New MINI." But there was no fan fair, no bells and whistles, no glitz and glamour, and no celebrity hosts. It was just cocktails and dinner with good food at Vyne, Hyve's boutique restaurant and gastropub in the heart of Bonifacio Global City, light banter with the management team of MINI Philippines (Owee Cruz, Mae Valdez, Richard Alarcon, Ryan Watson, Willy Tee Ten and Mike Chua), a few photo ops and a quick drive to MINI Philippines' BGC showroom in a Cooper S (or was it a Paceman?) That was Monday.
The hush-hush secret before today (and today is Wednesday) is the unveiling of the new generation MINI. Okay, I know some of you (like most of us) only know the MINI because of its popularity in "The Italian Job." I only know the MINI because of Charlize Therone. Okay, now I'm kidding. But yes, Mark Wahlberg and his Ocean's six team all drove MINI Coopers (actually, only the red MINI was a Cooper S; the others were Coopers) in that remake heist film which was also the highest-grossing film produced by Paramount in 2003. The classic MINI made a cameo appearance driven by Charlize. Ayayay!
Mini (styled MINI) is both the name of a subsidiary of BMW, and a car produced by that subsidiary since 2001. The car is marketed as a "retro" redesign of the original Mini, and manufactured in Cowley, Oxford, United Kingdom, in what was historically the Morris car plant.
The MINI (yes, that name stays all-caps for the official styled branding) is now a subsidiary of BMW and the car is marketed as a retro design of the original Mini and manufactured in the old Morris car plant. Morris and Austin were the two manufacturers of the first Mini cars. For the curious history buff, BMW actually made a curious decision to buy Britain's beleaguered Rover Group in 1994. Things didn't pan out that well and in 2000 BMW decided to dump all of the Rover's brands except one: Mini. The rest is history.
Going back to MINI Philippines, the new kid in town is the souped up version of the popular old version of the MINI Cooper and MINI Cooper S, to wit:
- MINI Twin Power turbo technology engine
- BMW patented Valvetronic variable valve control system
- Better driving performance
- Improved fuel consumption and reduced emission levels as much as 27 percent from predecessor versions
- Enhanced six-speed dynamics
- New automatic engine start/stop function – now this is something to reckon for!
- Optimized weight and aerodynamic drag
- Brake energy recuperation
- Energy-efficient electromechanical power steering
- Active cooling air flaps
- Extensive underbody trim
- Optimized suspension technology
- New driving modes in mid, sport or green mode
- Better ambient lighting
- Improved LED center displays
- Debut of Dynamic Damper Control
- Bigger exterior proportions for better agility and ride comfort
- Innovative driver assistance systems like the new MINI Heads-Up-Display
- Camera-based cruise control and distance control function
- Collision and pedestrian warning system with initial brake function
There is a host underlying detailed descriptions and adjacent addenda to each of items I listed above. Each one of us have our own pet peeves when it comes to cars, much less this retro-styled subcompact car that's better than your average subcompact. The United States automobile ranking system scores the 2014 MINI Cooper as:
- Affordable Small Cars (#17)
- Affordable Subcompact Cars (#8)
- Hatchbacks (#17)
- Affordable Convertibles (#4 but it hasn't been introduced in the Philippines… yet!)
The all-new 2014 MINI Cooper is said to have a good nimble handling that makes it a lot of fun to drive. The cabin is as classy as a BMW in a subcompact environment.
Standard Features:
Servotronic, 15" light alloy wheels Heli Spoke silver, Roof and mirror caps white, Floor Mats in Velour, Warning Triangle, Height adjustment for front passenger speed, Storage compartment package, Colour Line Carbon Black, Interior Surfaces Hazy Grey, MINI Excitement Package, Fog lights, Rain Sensor, Automatic Airconditioning, Speedometer with kilometer reading, On board computer, Lights package, Rear Fog light, Bluetooth Handsfree Interface, White Turn Indicators, Pepper Package, Cloth Firework upholstery.
Retail Price (incl. VAT): Php 2,100,000
Standard Features:
Servotronic, Multifunction for Steering Wheel, 17" light alloy wheels Tentacle spoke Silver, Sport Automatic transmission, Performance Control, Leather steering Wheel, Bonnet stripes, Floor mats in Velour, Warning Triangle, Height adjustment for front passenger seat, Sport seats for driver and passenger, Storage compartment Package, Color Line Carbon Black, Interior Surfaces Black Checkered, MINI Excitement Package, MINI Driving modes, Rain Sensor, Automatic Air conditioning, Cruise Control with breaking function, Speedometer with Kilometer reading, On board computer, Lights Package, LED Fog lights, LED Headlights, Rear Fog light, Radio MINI Visual Boost, MINI Connected, White Turn Indicators, Chilli Package, Cloth/Leather combination Diamond.
Retail Price (incl. VAT): P2,600,000
Note the following terms and conditions:
- Warranty coverage: 2 years unlimited mileage.
- Price is subject to confirmation upon order.
- Does not include LTO registration (Php 15,000) and motor vehicle insurance.
- Price and specifications are subject to change without prior notice
So, is it a good deal or what? Come by the MINI Philippines showroom at the corner of 5th Avenue and 26th Street in Bonifacio Global City, Taguig City now and experience the pleasure of driving home a great subcompact yet very stylish car.
And who says it's only got to be an Italian Job?
British United Automobiles, Inc.
5th Ave. and 26th St., Bonifacio Global City
Taguig City 1634
Photos by MINI Philippines | Ted Claudio | @raffypekson


text:
Out of Stock
The item you're looking for is currently unavailable.
The "Trucking: Tractor-Trailer Driver Video Series is the perfect companion to "Trucking: Tractor-Trailer Driver Handbook/Workbook. Created with the cooperation of the Professional Truck Driver Institute, Inc. (PTDI), these videos can be used as part of Delmar Learning's complete turnkey tractor-trailer driver training system or as part of any existing driver-training program. The content closely follows the "Handbook/Workbook, demonstrating the procedures and practices related to skilled driving.PTDI is the author of 'Introduction To Trucking Basic Control; Shiftng, Module 6 And 7', published 2003 under ISBN 9780766863934 and ISBN 076686393X.[read more]
You can find lots of answers to common customer questions in our FAQs
View a detailed breakdown of our shipping prices
Learn about our return policy
Still need help? Feel free to contact us
View college textbooks by subject
and top textbooks for college
With our dedicated customer support team, 30-day no-questions-asked return policy, and our price match guarantee, you can rest easy knowing that we're doing everything we can to save you time, money, and stress.


text:
National alert: Are you infected with this nail parasite?
|DO YOU WANT TO CURE TOE NAIL FUNGUS FAST? Click Play TO FIND OUT HOW
"If you are infected with toenail fungus, the biggest mistake you could ever make is to think this is nothing serious. It will cost you your life. (...) The number of serious cases with people suffering from toenail fungus is increasing at an alarming rate in America."
|Before it was too late!
If you wish to stop mails from us visit here
Or send mail to: firstname.lastname@example.com;
Or write us at :RiightVision Media 10685-B
Hazelhurst Dr. #19482Houston, TX 77043 USA
Or send mail to: firstname.lastname@example.com;
Or write us at :RiightVision Media 10685-B
Hazelhurst Dr. #19482Houston, TX 77043 USA
of this possession of self-assertion which she suddenly recognized as the strongest impulse of her being! "Free! Body and soul free!" she kept whispering. Josephine was kneeling before the closed door with her lips to the keyhold, imploring for admission. "Louise, open the door! I beg; open the door--you will make yourself ill. What are you doing, Louise? For heaven's sake open the door." "Go away. I am not making myself ill." No; she was drinking in a very elixir of life through that open window. Her fancy was running riot along those days ahead of her. Spring days, and summer days, and all sorts of days that would be her own. She breathed a quick prayer that life might be long. It was only yesterday she had thought with a shudder that life might be long. She arose at length and opened the door to her sister's importunities. There was a feverish triumph in her eyes, and she carried herself unwittingly like a goddess of Victory. She clasped her sister's waist, and together they descended the stairs. Richards stood waiting for them at the bottom. Some one was opening the front door with a latchkey. It was Brently Mallard who entered, a little travel-stained, composedly carrying his grip-sack and umbrella. He had been far from the scene of the accident, and did not even know there had been one. He stood amazed at Josephine's piercing cry; at Richards' quick motion to screen him from the view of his wife. When the doctors came they said she had died of heart disease--of the joy that kills.


text:
Tuesday, June 26, 2012
Not much more we can say about Vogie that we haven't already said. He pitched another great game, this one with the biggest stakes of the season so far, especially when you consider he was matched up with their no. 1 and the reigning Cy Young Award winner. The Voge-ster gives up his share of hits and walks, but he makes big pitches when he needs them, and he keeps the ball in the yard. The Dodgers got mostly ground ball hits and couldn't muster a killer blow. And you have to love Buster Posey nailing Dee Gordon (NL leader in SB and CS) trying to steal in the 5th inning: "I'm not havin' it!" I bitch and moan about stolen bases a lot, and it's not like I don't like them, it's just that I hate that CS in the box score. Nothing kills rallies like outs on the bases. (It was that classic "run" situation, leadoff hitter on first with two outs.) I note, however, that Pagan is 14 for 16 on the basepaths, Gregor Blanco is 13 for 16, and Melky Cabrera is 10 for 14 (the team is 59 for 78, or 77%). I like to see guys be 4 for 5 when they run--that's the break-even for my taste. If you are going to steal, make it count. And get extra-base hits while you're at it, that's even more my taste. But I'm quibbling. It was great win and the Giants flashed both power and dash to up end the Mighty Clayton.
Giants are once again in position to sweep a series. This time it is Tim Lincecum who has to follow a couple of dandy opening acts. Hey Timmy Jim, this is why they call you "Big Time."
5 comments:
Tom Tango et al.,*The Book* pp. 333-39, points out that gross figures about stolen bases aren't v informative. It's vital to know the inning and score at the time of the attempt. Overall, the break-even point is just under 70%, however, so that the Giants seem to be doing pretty well; and it may be that when one takes inning and score into account, they're doing better than pretty well.
- Tue Jun 26, 11:49:00 PM PDT
- M.C. O'Connor said...
FanGraphs has a good piece as well:
A baseball season is about 6 months/26 weeks long. If you attempt a steal once a week and are only thrown out once a month, that's 20/26 (77%). I can live that.
The problem with all baserunning analysis is that the value of the extra base is so dependent on the situation. Late in a close game a one-run strategy could be the difference-maker. Risking an out at second with your best power hitter up probably isn't worth it. Pitchers vary in their ability to hold runners. Running to stay out of a DP is different than stealing, as is forcing the infielders to move to make a hole for a hitter. Etc. Etc.
One thing the Giants seem to do, which I like, is taking the extra base on hits. I like to see pressure put on OFs and relay men to make good throws. The steal, to me, is a specialist's weapon. But ALL players can hustle and be "heads up" on the bases and try to get an edge. Well, maybe not Bengie.
- Wed Jun 27, 08:27:00 AM PDT
If you caught the statement by Kuip at the end of the game & the graphic they showed, it was the first back-to-back shutouts of LA by the Giants since August 15 & 16, 1987. Dravecky beat Valenzuela, 5-0, in the first game. In the second game, after outlasting Welch, the Giants won 1-0 behind a 10-inning complete game 3-hitter by Mike 'The God' LaCoss!
Here are the box scores for those games:
Can Tim extend the honorable streak? We'll find out shortly. The Giants need to bring out the lumber & get some of the heat off of him.
- Wed Jun 27, 08:33:00 AM PDT
- nomisnala said...
Tim with a game score of 75 tosses 7 shutout innings, and the giants finally sweep a 3 games series, and they did it with a series shutout. How many series shutouts have there been in the last few years, of series at least 3 games long?
- Wed Jun 27, 04:29:00 PM PDT
- M.C. O'Connor said...
Oh man, THREE STRAIGHT SHUTOUTS against the Dodger Scum!!!!!!!!
- Wed Jun 27, 06:41:00 PM PDT


text:
Dog food reviews
Member List
Dry Dog Foods
1 Star Dry Dog Food
Previous Product
Next Product
Lantmännen Doggy AB Bozita Extra
Date of last review
Sat March 22, 2008
Recommended By
Average Price
Average Rating
No recommendations
None indicated
None indicated
Calorie content:
346.33 Kcal
wheat, chicken meat meal, meat digest meal, animal fat, fresh chicken meat, maize germ, chicken bouillon, molasses, dried egg yolk, minerals, bone meal, beet fiber, brewer's yeast
protein 24.0 %
fat 12.0 %
fiber 2.0 %
ash 6.0 %
carbohydrates 46.0 %
calcium 1.2 %
magnesium 0.1 %
dietary fiber 2.0 %
biotine (vitamin H) 0.2 mcg
choline 1500.0 mg
iron 110.0 mg/kg
moisture 10.0 %
iodine 2.7 mg/kg
potassium 0.65 %
copper 13.4 mg/kg
manganese 30.0 mg/kg
minerals 6.0 %
sodium 0.5 %
niacin (vitamin- B3) 58.0 mg/kg
pantothenic acid 20.0 mg/kg
zinc 46.0 mg/kg
vitamin A 10270.0 IU/kg
vitamin B1 (thiamine) 6.0 mg/kg
vitamin B12 (cobalamin) 0.08 mg/kg
vitamin B2 (riboflavin) 7.0 mg/kg
vitamin B6 (pyridoxine) 4.0 mg/kg
vitamin C (ascorbic acid) 420.0 mg/kg
vitamin D 1080.0 IU/kg
vitamin E (tocopherol) 65.0 mg/kg
Post a Reply
Registered: October 2005
Posts: 3953
Review Date:
Sat March 22, 2008
Would you recommend the product?
| Price you paid?:
Not Indicated
| Rating:
Second ingredient is a named meat product
Insufficient meat content, low quality grain and meat products, controversial filler, sugar
The primary ingredient in this food is wheat. Wheat, although a whole grain, is believed by many to be the leading cause of food allergies in dog food. Even if this had been a high quality grain, we would still note that it is a grain and not a natural foodstuff for a canine. Dog food products should be based on meat, not on grains.
The second ingredient is a named meat product, in meal form. The third ingredient is of low quality. Unidentifiable even by species, it is the rendered product from mammal tissues, including bone, exclusive of blood, hair, hoof, horn, hide trimmings, manure, stomach and rumen contents, except in such amounts as may occur unavoidably in good processing practices.
A third meat ingredient is 4th on the ingredient list. This is not a meat meal, but instead is inclusive of water content (about 80%). Once this is removed, as it must be to create a dehydrated product, the ingredient will weigh around 20% of its wet weight. As ingredients are listed in order of weight, it is thus unlikely that this ingredient is truely amongst the most prolific in the food and would be more accurately placed further down the ingredient list. At wet weight only the 4th ingredient in the the food, it is likely that the true amount of this ingredient is significantly lower. Bone meal, further down the ingredient list, would inspire greater confidence as a fertilizer than as an ingredient in dog food.
Animal fat is an ingredient of unidentified origin for which it is impossible to determine species, source or quality. Unidentified ingredients are usually very low quality. AAFCO define this asobtained from the tissues of mammals and/or poultry in the commercial processes of rendering or extracting. It consists predominantly of glyceride esters of fatty acids and contains no additions of free fatty acids. If an antioxidant is used, the common name or names must be indicated, followed by the words "used as a preservative".
Beet pulp is a controversial filler. It is a by-product, being dried residue from sugar beets which has been cleaned and extracted in the process of manufacturing sugar. It is a controversial ingredient in dog food, claimed by some manufacturers to be a good source of fibre, and derided by others as an ingredient added to slow down the transition of rancid animal fats and causing stress to kidney and liver in the process. We note that beet pulp is an ingredient that commonly causes problems for dogs, including allergies and ear infections, and prefer not to see it used in dog food. There are less controversial products around if additional fibre is required. Molasses is an unneccessary source of sugar.
We note the food has added vitamins and minerals, but no information is given about these and may include synthetics.
Powered by:
Copyright 2006 All Enthusiast, Inc.
Trusted Gourmet
Terms of use
Privacy policy
Copyright © 2005 - 2009 DogFoodAnalysis.com.
All Rights Reserved.
Mesure d'audience ROI statistique webanalytics par