https://media.notthebee.com/articles/6418778b6bbe46418778b6bbe6.jpg
Dr. Fauci is on another one of his publicity tours, this time in DC with Mayor Muriel Bowser to guilt poor people into taking his experimental jab.
Not the Bee
Just another WordPress site
https://media.notthebee.com/articles/6418778b6bbe46418778b6bbe6.jpg
Dr. Fauci is on another one of his publicity tours, this time in DC with Mayor Muriel Bowser to guilt poor people into taking his experimental jab.
Not the Bee
https://www.percona.com/blog/wp-content/uploads/2023/03/lucas.speyer_an_underwater_high_tech_computer_server_a_dolpin_i_9337e5c5-e3c5-41dd-b0b1-e6504186488b-150×150.png
With a special focus on Percona Operator for MySQL
HAProxy, ProxySQL, MySQL Router (AKA MySQL Proxy); in the last few years, I had to answer multiple times on what proxy to use and in what scenario. When designing an architecture, many components need to be considered before deciding on the best solution.
When deciding what to pick, there are many things to consider, like where the proxy needs to be, if it “just” needs to redirect the connections, or if more features need to be in, like caching and filtering, or if it needs to be integrated with some MySQL embedded automation.
Given that, there never was a single straight answer. Instead, an analysis needs to be done. Only after a better understanding of the environment, the needs, and the evolution that the platform needs to achieve is it possible to decide what will be the better choice.
However, recently we have seen an increase in the usage of MySQL on Kubernetes, especially with the adoption of Percona Operator for MySQL. In this case, we have a quite well-defined scenario that can resemble the image below:
In this scenario, the proxies must sit inside Pods, balancing the incoming traffic from the Service LoadBalancer connecting with the active data nodes.
Their role is merely to be sure that any incoming connection is redirected to nodes that can serve them, which includes having a separation between Read/Write and Read Only traffic, a separation that can be achieved, at the service level, with automatic recognition or with two separate entry points.
In this scenario, it is also crucial to be efficient in resource utilization and scaling with frugality. In this context, features like filtering, firewalling, or caching are redundant and may consume resources that could be allocated to scaling. Those are also features that will work better outside the K8s/Operator cluster, given the closer to the application they are located, the better they will serve.
About that, we must always remember the concept that each K8s/Operator cluster needs to be seen as a single service, not as a real cluster. In short, each cluster is, in reality, a single database with high availability and other functionalities built in.
Anyhow, we are here to talk about Proxies. Once we have defined that we have one clear mandate in mind, we need to identify which product allows our K8s/Operator solution to:
To identify the above points, I have simulated a possible K8s/Operator environment, creating:
We will have very simple test cases. The first one has the scope to define the baseline, identifying the moment when we will have the first level of saturation due to the number of connections. In this case, we will increase the number of connections and keep a low number of operations.
The second test will define how well the increasing load is served inside the previously identified range.
For documentation, the sysbench commands are:
Test1
sysbench ./src/lua/windmills/oltp_read.lua --db-driver=mysql --tables=200 --table_size=1000000 --rand-type=zipfian --rand-zipfian-exp=0 --skip_trx=true --report-interval=1 --mysql-ignore-errors=all --mysql_storage_engine=innodb --auto_inc=off --histogram --stats_format=csv --db-ps-mode=disable --point-selects=50 --reconnect=10 --range-selects=true –rate=100 --threads=<#Threads from 2 to 4096> --time=1200 run
Test2
sysbench ./src/lua/windmills/oltp_read.lua --mysql-host=<host> --mysql-port=<port> --mysql-user=<user> --mysql-password=<pw> --mysql-db=<schema> --db-driver=mysql --tables=200 --table_size=1000000 --rand-type=zipfian --rand-zipfian-exp=0 --skip_trx=true --report-interval=1 --mysql-ignore-errors=all --mysql_storage_engine=innodb --auto_inc=off --histogram --table_name=<tablename> --stats_format=csv --db-ps-mode=disable --point-selects=50 --reconnect=10 --range-selects=true --threads=<#Threads from 2 to 4096> --time=1200 run
As indicated here, I was looking to identify when the first Proxy will reach a dimension that would not be manageable. The load is all in creating and serving the connections, while the number of operations is capped at 100.
As you can see, and as I was expecting, the three Proxies were behaving more or less the same, serving the same number of operations (they were capped, so why not) until they weren’t.
MySQL router, after the 2048 connection, could not serve anything more.
NOTE: MySQL Router actually stopped working at 1024 threads, but using version 8.0.32, I enabled the feature: connection_sharing. That allows it to go a bit further.
Let us take a look also the latency:
Here the situation starts to be a little bit more complicated. MySQL Router is the one that has the higher latency no matter what. However, HAProxy and ProxySQL have interesting behavior. HAProxy performs better with a low number of connections, while ProxySQL performs better when a high number of connections is in place.
This is due to the multiplexing and the very efficient way ProxySQL uses to deal with high load.
Everything has a cost:
HAProxy is definitely using fewer user CPU resources than ProxySQL or MySQL Router …
.. we can also notice that HAProxy barely reaches, on average, the 1.5 CPU load while ProxySQL is at 2.50 and MySQL Router around 2.
To be honest, I was expecting something like this, given ProxySQL’s need to handle the connections and the other basic routing. What was instead a surprise was MySQL Router, why does it have a higher load?
This test highlights that HAProxy and ProxySQL can reach a level of connection higher than the slowest runner in the game (MySQL Router). It is also clear that traffic is better served under a high number of connections by ProxySQL, but it requires more resources.
When the going gets tough, the tough get going
Let’s remove the –rate limitation and see what will happen.
The scenario with load changes drastically. We can see how HAProxy can serve the connection and allow the execution of more operations for the whole test. ProxySQL is immediately after it and behaves quite well, up to 128 threads, then it just collapses.
MySQL Router never takes off; it always stays below the 1k reads/second, while HAProxy served 8.2k and ProxySQL 6.6k.
Looking at the latency, we can see that HAProxy gradually increased as expected, while ProxySQL and MySQL Router just went up from the 256 threads on.
To observe that both ProxySQL and MySQL Router could not complete the tests with 4096 threads.
Why? HAProxy always stays below 50% CPU, no matter the increasing number of threads/connections, scaling the load very efficiently. MySQL router was almost immediately reaching the saturation point, being affected by the number of threads/connections and the number of operations. That was unexpected, given we do not have a level 7 capability in MySQL Router.
Finally, ProxySQL, which was working fine up to a certain limit, reached saturation point and could not serve the load. I am saying load because ProxySQL is a level 7 proxy and is aware of the content of the load. Given that, on top of multiplexing, additional resource consumption was expected.
Here we just have a clear confirmation of what was already said above, with 100% CPU utilization reached by MySQL Router with just 16 threads, and ProxySQL way after at 256 threads.
HAProxy comes up as the champion in this test; there is no doubt that it could scale the increasing load in connection without being affected significantly by the load generated by the requests. The lower consumption in resources also indicates the possible space for even more scaling.
ProxySQL was penalized by the limited resources, but this was the game, we had to get the most out of the few available. This test indicates that it is not optimal to use ProxySQL inside the Operator; it is a wrong choice if low resource and scalability are a must.
MySQL Router was never in the game. Unless a serious refactoring, MySQL Router is designed for very limited scalability, as such, the only way to adopt it is to have many of them at the application node level. Utilizing it close to the data nodes in a centralized position is a mistake.
I started showing an image of how the MySQL service is organized and want to close by showing the variation that, for me, is the one to be considered the default approach:
This highlights that we must always choose the right tool for the job.
The Proxy in architectures involving MySQL/Percona Server for MySQL/Percona XtraDB Cluster is a crucial element for the scalability of the cluster, no matter if using K8s or not. Choosing the one that serves us better is important, which can sometimes be ProxySQL over HAProxy.
However, when talking about K8s and Operators, we must recognize the need to optimize the resources usage for the specific service. In that context, there is no discussion about it, HAProxy is the best solution and the one we should go to.
My final observation is about MySQL Router (aka MySQL Proxy).
Unless there is a significant refactoring of the product, at the moment, it is not even close to what the other two can do. From the tests done so far, it requires a complete reshaping, starting to identify why it is so subject to the load coming from the query more than the load coming from the connections.
Great MySQL to everyone.
Percona Database Performance Blog
https://theawesomer.com/photos/2023/03/we_didnt_start_the_fire_leo_moracchioli_t.jpg
Wheel of Fortune, Sally Ride, heavy metal suicide. Leo Morachiolli didn’t start the fire, but he did an impressive job covering Billy Joel’s wordy 1989 hit, adding fuel to the inferno with his hard-edged guitar and gravelly vocals. If you’re waiting for Joel to update the song for the 21st century, don’t hold your breath.
The Awesomer
https://laravelnews.s3.amazonaws.com/images/laravel-valet-version-four.png
Valet 4 is officially released! Let’s look into what v4 offers and how you can upgrade your local install today.
Valet was originally introduced in May 2016 with this incredible video. Valet v2 was released soon after, bringing about the move from Caddy to Nginx. But after that, development on Valet slowed; as Taylor has often pointed out, “at that point, Valet was feature complete.”
However, when I picked up maintenance of Valet a few years back, there were two things I noticed: first, that many people needed different versions of PHP for their different sites; and second, that miscellaneous features and bug fixes addressed over the years made the codebase a bit difficult to reason with at times.
Valet v3 was released in March 2022, with the primary focus on adding support for multiple versions of PHP running in parallel on the same machine.
And now, we’re looking at Valet v4.
The most important change to Valet 4 is something you can’t even see from the outside: the internals of the project has been re-architected and tested heavily. Just to be clear, they’ve been re-architected back toward the style of simplicity Taylor and Adam’s original code had. But they’re now covered with all forms of unit and integration tests, and the changes made since Valet 2 are now much better integrated.
What does that mean?
Valet 4 is the most stable, easy to debug, and easy to fix version of Valet yet.
There are a few user-facing new features:
valet status
command: If you run valet status
, you’ll get a table showing you the “health” of a few important aspects of your Valet application. This is helpful both because you can use it when you’re debugging, but, like any good CLI tool, it’ll also return codes for success or failure that other CLI tools can consume.valet share-tool expose
and, if you don’t have Expose installed, it’ll prompt you to install it. Once you’ve set up your Expose token, you’re ready to share using the same valet share
command you’re familiar with.If you’re upgrading from Valet 3, here’s my preferred way to upgrade:
~/.composer/composer.json
file and update your Valet requirement to "^4.0"
composer global update laravel/valet
valet install
Make sure you run valet install
, as it’ll check your system’s compatibility and upgrade some configuration files for you.
If you have any custom drivers, you’ll want to update them to match the new syntax (basically, drivers are now namespaced and have type hints and return types).
.valetphprc
If you use .valetphprc
to define your sites’ PHP versions, you’ll want to rename those files to .valetrc
and change their contents; .valetphprc
files just contain a PHP Brew formula (e.g. php@8.1
), but the new .valetrc
files are broader config files, so you’ll need to prefix the formula with php=
.
So if your project had this .valetphprc
file:
php@8.1
You’ll want to rename it to .valetrc
and update its contents to this:
php=php@8.1
Valet 4 requires PHP 8.0+ to be installed on your system via Homebrew. As I mentioned already, you can use Valet’s isolation feature to set individual sites to use older versions of PHP, back to 7.1.
However, if you have a reason you need to use PHP 7.1-7.4 as your primary linked PHP (meaning if you just type php -v
you see something between 7.1 and 8.0), you can do that! Just make sure that you have a modern version of PHP installed on your machine, and Valet will use that version to run its internal commands.
However, a quick warning: If you use Valet 4 and your primary linked version of PHP is lower than PHP 8, all of your local Valet CLI commands will run a bit more slowly, as they have to find your modern PHP install and proxy their calls through it.
That’s it! The primary goal of Valet 4 is stability, but it also opens up some great new options for the future. First, the .valetrc
file is much more powerful than .valetphprc
was, and we can make it a lot more configurable. And second, I dropped a concept called Extensions
that was basically entirely unused, with the hope of building a plugin system sometime in the near future.
If you followed my journey of rebuilding Valet for v4 on Twitter, you might have seen that I attempted to make it work on Linux. Sadly, that wasn’t successful, but I still have dreams of one day attempting it again. No promises… but it’s still a dream!
I hope you all love Valet 4. Enjoy!
Laravel News
Laravel OpenWeather API (openweather-laravel-api) is a Laravel package to connect Open Weather Map APIs ( https://openweathermap.org/api ) and access free API services (current weather, weather forecast, weather history) easily.
Install the package through Composer.
On the command line:
composer require rakibdevs/openweather-laravel-api
If Laravel > 7, no need to add provider
Add the following to your providers
array in config/app.php
:
'providers' => [ // ... RakibDevs\Weather\WeatherServiceProvider::class, ], 'aliases' => [ //... 'Weather' => RakibDevs\Weather\Weather::class, ];
Add API key and desired language in .env
OPENWAETHER_API_KEY=
OPENWAETHER_API_LANG=en
Publish the required package configuration file using the artisan command:
$ php artisan vendor:publish
Edit the config/openweather.php
file and modify the api_key
value with your Open Weather Map api key.
return [ 'api_key' => env('OPENWAETHER_API_KEY', ''), 'onecall_api_version' => '2.5', 'historical_api_version' => '2.5', 'forecast_api_version' => '2.5', 'polution_api_version' => '2.5', 'geo_api_version' => '1.0', 'lang' => env('OPENWAETHER_API_LANG', 'en'), 'date_format' => 'm/d/Y', 'time_format' => 'h:i A', 'day_format' => 'l', 'temp_format' => 'c' // c for celcius, f for farenheit, k for kelvin ];
Now you can configure API version from config as One Call API is upgraded to version 3.0. Please set available api version in config.
Here you can see some example of just how simple this package is to use.
use RakibDevs\Weather\Weather; $wt = new Weather(); $info = $wt->getCurrentByCity('dhaka'); // Get current weather by city name
Access current weather data for any location on Earth including over 200,000 cities! OpenWeather collect and process weather data from different sources such as global and local weather models, satellites, radars and vast network of weather stations
// By city name $info = $wt->getCurrentByCity('dhaka'); // By city ID - download list of city id here http://bulk.openweathermap.org/sample/ $info = $wt->getCurrentByCity(1185241); // By Zip Code - string with country code $info = $wt->getCurrentByZip('94040,us'); // If no country code specified, us will be default // By coordinates : latitude and longitude $info = $wt->getCurrentByCord(23.7104, 90.4074);
{
"coord": {
"lon": 90.4074
"lat": 23.7104
}
"weather":[
0 => {
"id": 721
"main": "Haze"
"description": "haze"
"icon": "50d"
}
]
"base": "stations"
"main": {
"temp": 26
"feels_like": 25.42
"temp_min": 26
"temp_max": 26
"pressure": 1009
"humidity": 57
}
"visibility": 3500
"wind": {
"speed": 4.12
"deg": 280
}
"clouds": {
"all": 85
}
"dt": "01/09/2021 04:16 PM"
"sys": {
"type": 1
"id": 9145
"country": "BD"
"sunrise": "01/09/2021 06:42 AM"
"sunset": "01/09/2021 05:28 PM"
}
"timezone": 21600
"id": 1185241
"name": "Dhaka"
"cod": 200
}
Make just one API call and get all your essential weather data for a specific location with OpenWeather One Call API.
// By coordinates : latitude and longitude $info = $wt->getOneCallByCord(23.7104, 90.4074);
4 day forecast is available at any location or city. It includes weather forecast data with 3-hour step.
// By city name $info = $wt->get3HourlyByCity('dhaka'); // By city ID - download list of city id here http://bulk.openweathermap.org/sample/ $info = $wt->get3HourlyByCity(1185241); // By Zip Code - string with country code $info = $wt->get3HourlyByZip('94040,us'); // If no country code specified, us will be default // By coordinates : latitude and longitude $info = $wt->get3HourlyByCord(23.7104, 90.4074);
Get access to historical weather data for the previous 5 days.
// By coordinates : latitude, longitude and date $info = $wt->getHistoryByCord(23.7104, 90.4074, '2020-01-09');
Air Pollution API provides current, forecast and historical air pollution data for any coordinates on the globe
Besides basic Air Quality Index, the API returns data about polluting gases, such as Carbon monoxide (CO), Nitrogen monoxide (NO), Nitrogen dioxide (NO2), Ozone (O3), Sulphur dioxide (SO2), Ammonia (NH3), and particulates (PM2.5 and PM10).
Air pollution forecast is available for 5 days with hourly granularity. Historical data is accessible from 27th November 2020.
// By coordinates : latitude, longitude and date $info = $wt->getAirPollutionByCord(23.7104, 90.4074);
Geocoding API is a simple tool that we have developed to ease the search for locations while working with geographic names and coordinates.
-> Direct geocoding converts the specified name of a location or area into the exact geographical coordinates;
-> Reverse geocoding converts the geographical coordinates into the names of the nearby locations.
// By city name $info = $wt->getGeoByCity('dhaka'); // By coordinates : latitude, longitude and date $info = $wt->getGeoByCity(23.7104, 90.4074);
Laravel Open Weather API is licensed under The MIT License (MIT).
Laravel News Links
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMbtjUuceQaJ_JiqGW2aJ7bzET2TPRNs-7O888yvYKFxk8rgzPuhjVvS1eZPFQ7wU55UJIqYmKSoW2iC-CiucemUrlb_T_TTOMLPkEG-fOsKu9tO3hOlHeLWM8xvcFSVIgPSAfQSBchQTrmm6o7MCFkzT-90PlwsI9WVx_xL62ZqR9v5FAjclOFtsO/w400-h254/Elephant%20stew.png
Found on Gab (clickit to biggit):
I had to laugh at the instructions.
I’ve been present when an elephant that was destroying crops was shot near an African village. The villagers swarmed the carcass, armed with machetes, axes and other edged instruments, and proceeded to have a gigantic meat-eating binge that lasted three days. They dismembered that carcass from inside and out, literally: some people crawled inside the belly cavity and cut their way out, while others stood on the ribs and cut their way in. When an errant machete blade from one side or the other cut into someone on the other side of the skin, there were screams of outrage and anger; but mostly they were too busy eating (yes, even raw meat!) to care.
At the end of three days, all that was left were the remains of the entrails, and the huge bones of the elephant skeleton. Sixty-odd villagers had eaten until they bulged (literally): their stomachs were so distended I was surprised they could still move. Of course, in African heat, with no refrigeration available, the meat had already spoiled by the third day, but they ate and ate and ate so as to waste as little as possible of the precious nutrition deposited on their doorsteps by the Game Department.
Perhaps they should have tried this recipe . . .
Peter
Bayou Renaissance Man
https://theawesomer.com/photos/2022/03/molten_steel_coiling_t.jpg
Redditor arcedup works in a steel mill and wanted to test out the video capabilities of their phone. While they were at it, they captured this wonderfully satisfying clip of molten hot steel being turned into a coiled rod. Is it wrong that we want to make the world’s largest Slinky with it?
The Awesomer
B.L.U.F. An analysis/opinion of the State’s attempt to move certain arms out from the protection of the Second Amendment.
This is a long running argument from the anti-gun rights people. The gist is always of the “this modern thing didn’t exist in 1791 so it isn’t covered by the second amendment.” These same people are saying this on phones, computers, The Internet, which the firmly believe are covered under the first Amendment, even though those things would not have been known at the time of the founding.
The question is legitimate, so lets take it to an extreme.
Hagar reported to me that she often times has discussions with anti-gun people and they will ask something like “Well, do you think people should be able to own nuclear weapons!?!?!?”
She reports that most of them are shocked when she replies in the affirmative “Yes, they should be able to legally own nuclear weapons.” There is more to our discussion, I’ll get to that later.
The term was applied, then as now, to weapons that were not specifically designed for military use and were not employed in a military capacity. For instance, Cunningham’s legal dictionary gave as an example of usage: “Servants and labourers shall use bows and arrows on Sundays, & c. and not bear other arms.” See also, e.g., An Act for the trial of Negroes, 1797 Del. Laws ch. XLIII, § 6, in 1 First Laws of the State of Delaware 102, 104 (J. Cushing ed.1981 (pt. 1)); see generally State v. Duke, 42 Tex. 455, 458 (1874) (citing decisions of state courts construing “arms”). Although one founding-era thesaurus limited “arms” (as opposed to “weapons”) to “instruments of offence generally made use of in war,” even that source stated that all firearms constituted “arms.” 1 J. Trusler, The Distinction Between Words Esteemed Synonymous in the English Language 37 (3d ed. 1794) (emphasis added).
— District of Columbia v. Heller, 554 US 570 – Supreme Court 2008 P.2791
Here we have the short of it [w]eapons of offence, or armour of defence.
Id, citing Samuel Johnson’s dictionary of 1773
Are “nuclear weapons” weapons of offence? Yes, by the clear text of the Second Amendment supported by multiple sources at the time of the ratification of the Bill of Rights.
But nuclear weapons were not in existence at the time of the founding and the Founding Fathers could not have anticipated the horrific destructive power of such weapons. Again, Justice Scalia answers us.
Under the instructions given by the Supreme Court in Heller it is clear that nuclear weapons are arms.
But the argument goes on that the arm must be “bearable” to be considered covered under the Second Amendment. We know from historical fact that this was not the understanding at the time of the founding. We know this because many civilians owned cannon and even warships. In fact the US Government was known to issue sanctions to warship owners to have them engage in combat on the high seas with the enemies of the United States.
Justice Scalia addresses this issue. He is addressing the question in Heller in regards to individual right vs. collective right so his analysis is not a direct answer for us.
This leaves the question slightly open as to the question of size limitations on arms that are protected by the Second Amendment. We know that Heller clearly states that pistols and other handguns are. This has been extended to the sorts of long guns and shotguns that can be shouldered. It has been extended to weapons that are too heavy to shoulder but can be fired by one man from a bipod. I.e. a .50 cal semi-auto or bolt action rifle.
What about crew served weapons? Is a 60mm M224A1 mortar covered? How about the 81mm M252A1? How about the 120mm M120/M121, are they covered?
If those are covered are the M119 105mm Howitzer covered and the M777 155mm Howitzer? Or even the M110 Self-Propelled Howitzer. Those are huge. Are they covered?
The answer to all of that seems to be “yes”. The text of the Second Amendment does extend to “arms” that can not be carried by just one man but must instead have some other way of conveyance. It seems clear that a 16″ 3 Gun turret from a Wisconsin class Battleship would be covered arms.
From this, it seems clear that nuclear weapons are covered under the Second Amendment.
According to the Constitution the answer is shall not be infringed
According to the Supreme Court, there are acceptable regulations and limitations on the right to keep and bear arms.
…is neither a regulatory straightjacket nor a regulatory blank check…
which leads to the question of when it the analogical reasoning within the limits? That is not relevant here.
This allows the state to raise the question of what laws are consistent with Nation’s historical tradition of firearm(arms) regulation.
So far the state has not been able to produce any law, in my opinion, from the correct time period that supports the banning of a class of weapon.
What they have been able to do is to find multiple laws regarding fire safety in regards to gunpowder. I submit that since the possibilities of a radiation mishap does exist and that does not infringe on your ability to keep and bear the nuclear weapon, that the state could have storage requirements that are for safety purposes.
Note, when I say “safety purposes” that doesn’t mean stuff like “It must be kept disassembled with its fissionable materials in a different county.” It means things like radiation sensors that are tested and monitored. Containers that are designed to low radiation leakage to a reasonable level and so forth.
In my opinion this type of safety law would fall within the text, history and tradition requirements of both Heller and Bruen.
Currently, the Supreme Court has put another limitation on what arms are covered within the scope of the Second Amendment.
Chief Justice Waite ruled that neither the First nor Second Amendments limited the powers of the state government or individuals. Wikipedia
The right to keep and bear arms exists separately from the Constitution and is not solely based on the Second Amendment, which exists to prevent Congress from infringing the right.
Justia
[T]hose in common use for lawful purposes
Heller is the phrase that much of our current litigation is founded on. If an arm is in common use for lawful purposes then that arm is not “Unusual”.
This links back to …finds support in the historical tradition of prohibiting the carrying of dangerous and unusual weapons.
Id. at P. 2786 is the other part of this.
What this means is that nuclear weapons fail “in common use for lawful purposes” so they are unusual weapons and they are also “dangerous” which means that laws from the founding that prohibited carrying “dangerous and unusual” weapons can be used to justify carry regulations in regards to nuclear weapons today.
More to come.
Gun Free Zone
http://img.youtube.com/vi/RjNcTBXTk4I/0.jpg
There was a time when movies based on video games tried to distance themselves from their source material. "This ain’t no game," bragged the poster for the 1993’s live-action Super Mario Bros. film. Times have changed: The final trailer for The Super Mario Bros. Movie by Illumination leans hard into its origins. This is absolutely a game, it says. See? Here’s a scene that looks like New Super Mario Bros. U Deluxe, and another one that looks just like Mario Kart 8 Deluxe.
If you were hoping to hear more of Chris Pratt’s Mario voice, you won’t find much new here — but the final trailer does give viewers a clear look at the tone the movie is going for. We watch Bowser list off an army of familiar video game enemies. We watch Mario and Donkey Kong use power mushrooms and fire flowers as they run through a training course that looks like a traditional Mario level. We see Mario and Peach race through a brightly rendered Rainbow Road. It looks familiar. It looks fun. And it looks like a game, but with better graphics.
That’s no surprise. According to directors Aaron Horvath and Michael Jelenic, Illumination has worked closely with Nintendo to make sure the film feels right. The directors also say that Illumination has improved its lighting and rendering technology to help push Super Mario Bros. Movie to the next level "beyond anything Illumination has ever done."
As for that Mario voice? You’ll finally be able to hear the full performance when the film hits theaters next month. The Super Mario Bros. Moviereleases on April 5, 2023.
This article originally appeared on Engadget at https://www.engadget.com/the-final-trailer-for-the-super-mario-bros-movie-looks-more-like-a-game-than-ever-231926362.html?src=rssEngadget
https://harrk.dev/content/images/2023/03/QR-Code-Generator-in-Laravel-10-Tutorial.webp
In this post, we will look at generating QR codes within your Laravel applications.
First, we will need to require the simple-qrcode package that provides first-party support for Laravel. The package itself wraps the Bacon/BaconQrCode package which itself is a port of the ZXing library but for PHP.
If you wish – you may directly interact with the BaconQrCode package without using simple-qrcode. However, simple-qrcode provides a better developer experience when used with Laravel. Additionally, with out-of-the-box support for overlaying images on QR codes.
With the context blurb out of the way. Let’s dig in!
Spin up a new Laravel 10 project (or step over this if you already have a project ready).
$ laravel new qrcodegenerator
Set up your database connection as per your own preference. Then install the simple-qrcode package via Composer.
$ composer require simplesoftwareio/simple-qrcode "~4"
Optional! If you want to create QR codes in .png
format. You will need to install the imagick
extension. In most cases, all you need to do is install via pecl
with pecl install imagick
. If that does not work for you, then Google is your friend here as it goes beyond the topic of this article.
Now we need to wire up a controller and route before we can pull back a QR code in our browser.
Create a new QrCodeController
.
$ php artisan make:controller QrCodeController
And then reference the controller in our routes/web.php file.
<?php
use App\Http\Controllers\QrCodeController;
use Illuminate\Support\Facades\Route;
Route::get('/', [QrCodeController::class, 'show']);
Opening up the URL in our browser gives us a blank page at this point. Also as I’m using Valet here, I only need to enter the foldername.test
to view the project in my browser. Your setup may be different so you do you, whether that’s php artisan serve
or something else.
At the very bare minimum, you can call the QrCode
facade alongside generate
with something to render. And you’ll get a QR code back.
In my QrCodeController
I am creating a QR code with all the default settings with the following content “Hello, World!”.
<?php
namespace App\Http\Controllers;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
class QrCodeController extends Controller
{
public function show()
{
return QrCode::generate(
'Hello, World!',
);
}
}
Refresh the page in the browser and…
Alright so how about something a little more interesting? A splash of colour? Let’s use a couple of methods that allow us to change the background colour, foreground colour, and margin.
public function show()
{
return QrCode::size(200)
->backgroundColor(255, 255, 0)
->color(0, 0, 255)
->margin(1)
->generate(
'Hello, World!',
);
}
And here’s the result:
Let’s try something that makes our QR codes stand out. And I’m not talking about colours anymore.
We can actually modify the style and eye (the three corners) of the QR code. Try this out:
return QrCode::size(200)
->style('dot')
->eye('circle')
->color(0, 0, 255)
->margin(1)
->generate(
'Hello, World!',
);
Result:
Before closing this section. One more on colours: gradients.
$from = [255, 0, 0];
$to = [0, 0, 255];
return QrCode::size(200)
->style('dot')
->eye('circle')
->gradient($from[0], $from[1], $from[2], $to[0], $to[1], $to[2], 'diagonal')
->margin(1)
->generate(
'Hello, World!',
);
By specifying a from and to colour, alongside a type of gradient (vertical, horizontal, etc). You can create something really cool!
To overlay an image in a QR code – we’ll need to change the way we do a few things.
To prepare for this I have dropped an image (twitter.jpg) in my storage/app folder. Then by calling ->merge($filepath)
, simple-qrcode will load that image and overlay it onto the QR code.
If you want to pull in the image data yourself, you can replace merge
with mergeString
. Eg: ->mergeString(Storage::get($path))
.
Merging an image is only supported with png
QR codes, so we need to specify the format on this, too.
public function show()
{
$data = QrCode::size(512)
->format('png')
->merge('/storage/app/twitter.jpg')
->errorCorrection('M')
->generate(
'https://twitter.com/HarryKir',
);
return response($data)
->header('Content-type', 'image/png');
}
Then the result of all this:
You may have noticed the line in regards to errorCorrection
. When we overlay an image, part of the QR code’s data becomes obscured.
By default, the errorCorrection is set to the lowest value (‘L’). If you attempt to scan your QR code like this, it’s likely that the QR code will not scan. To remedy this we adjust the errorCorrection level up a notch until our code is scannable.
The various levels are:
The higher the correction level, the more “noisy” the QR code becomes. Preferably you want the lowest correction level alongside a scannable QR code for the sake of keeping up appearances.
To return a download response, you can either store the QR code as a file and return the path with return response()->download($path);
or stream the contents of the QR code without using the filesystem.
An example of using streamDownload
to do this:
public function download()
{
return response()->streamDownload(
function () {
echo QrCode::size(200)
->format('png')
->generate('https://harrk.dev');
},
'qr-code.png',
[
'Content-Type' => 'image/png',
]
);
}
Since we’ve been using a Facade all along, generating a QR code in Blade is as simple as repeating the above steps. Call the facade, customise as required, and call generate.
{!! QrCode::size(256)->generate('https://google.com') !!}
Or another approach, encode the data within an image tag manually. For example, if you need to change the image type for whatever reason.
<img src="data:image/png;base64, {!! base64_encode(QrCode::format('png')->size(256)->generate('https://google.com')) !!} ">
Alright, so we’ve been using URLs in these examples. Mobile devices are clever enough to figure out how to handle these when scanned, but we can go a step further.
If you want to read the long version of this. Check out the ZXing’s Wiki page.
To summarise: simple-qrcode has a couple of helpers to specify the data the QR code will contain. You can replace the generate
method with any of these.
Here are a few examples:
Open a blank email addressed to “hello@example.com”.
QrCode::size(200)->email('hello@example.com');
Open an email with a predefined subject and body.
QrCode::size(200)->email('hello@example.com', 'Hello World', 'This is a test message.');
QrCode::size(200)->phoneNumber('555-555-5555');
Send an SMS text message to 555-555-5555 with a prewritten message, “Hi!”.
QrCode::size(200)->SMS('555-555-5555', 'Hi!');
Share Wi-Fi credentials for your visitors.
QrCode::size(200)->wiFi([
'encryption' => 'WPA/WEP',
'ssid' => 'SSID of the network',
'password' => 'Password of the network',
'hidden' => 'Whether the network is a hidden SSID or not.'
]);
Share a location by providing a latitude and longitude.
QrCode::size(200)->geo(51.378638, -0.100897);
To see more advance options for QR code customisation, refer to the documentation for simple-qrcode.
As for some real world examples of this package in action. I use simple-qrcode for generating QR codes for my QR code tracking SaaS.
QRMetric – Your Dynamic QR Code Buddy
Create Dynamic QR Codes that can be modified without requiring you to redistribute a new QR code. Can be changed any time, any place, anywhere.
Otherwise, if generating QR codes with Javascript is your thing. Consider checking out the node-qrcode library. I use this for generating QR codes on a static site, without any server involvement altogether.
Random QR Code Generator
RandomQR is a QR Code Generator for those times when you just need a random QR image and nothing more. Simple, easy, and fast.
Laravel News Links