For more videos on people's struggles, please subscribe to our YouTube channel. During this pandemic, the Narendra Modi-led Bharti Chanta Party government in India has pushed through multiple legislations that are a direct assault on people's rights. The latest among these are three bills on agriculture. The government passed these three bills, brazenly flouting parliamentary rules and ignoring the protesting farmers across the country. Two of these were passed on Sunday, September 20th. The Farmers and Produce Trade and Commerce Promotion and Facilities Bill 2020 and Farmers Empowerment and Protection Agreement on Price Assurance and Farm Services Bill 2020. Members from opposition parties walked out of the parliament and protest of the manner in which these bills were pushed through. However, the BJP government remained underturbed. On Tuesday, September 22nd, the third bill, Essential Commodities Amendment Bill 2020, was passed in the upper house of the parliament along with six other bills in the absence of opposition parliament members. What are these farm bills and why are farmers opposing them? The first bill is the Farmers' Produce Trade and Commerce Promotion and Facilitation Bill 2020, which analysts have dubbed as the APMC Bypass Bill 2020. APMCs are agricultural produce market committees are essentially government regulated market places for agricultural produce. These markets are places where farmers can sell certain crops such as wheat and rice at minimum support prices which are fixed. The MSPs and the APMCs were introduced as a way of providing remunerative prices and a short procurement of crops to farmers. While the implementation of these policies has been far from perfect, the APMC Bypass Bill as it's being called is set to further weaken these provisions. This bill will set up a new unregulated market space called the trading area which will have no oversight. While the government is trying to present this as a way for farmers to access new markets, farmers have always been free to sell their produce to private players. However, this move will incentivize traders to move out of the regulated markets and farmers will find it increasingly difficult to get guaranteed prices for their crops. What is going to happen is the big agribusinesses so-called aggregators, sponsors and processors and so on, they are going to dictate the prices. There is not going to be any control over them. The earlier system had a price support mechanism and also a mechanism of price support mechanism for the farmers and a price control for the consumers. These are being totally dismantled by these ordinances. Any kind of protection that the farmers would have had as far as price support is concerned, that is not going to be any longer there. The APMCs also have other advantages. They provide collective bargaining power to farmers and they also provide information to government to determine the prices of crops. With the government gradually pulling out of crop procurement, it will have no way of gauging prices and intervening in the market in the interest of farmers if needed. The farmers will be left at the mercy of big capital. Linked closely to this is the Essential Commodities Amendment Bill 2020, which is also being called the Food Holding Freedom for Corporates Bill 2020. With the passing of this bill, various items such as cereals, pulses, oil seeds, edible oils, onions and potatoes have been removed from the list of essential commodities. This bill also essentially legitimizes holding of produce by private companies as it removes any limits on stock holding. They can thus take advantage of high prices with the government having no knowledge of what stocks exist with who, when and where. This is being done in the name of attracting private investment in post-harvest infrastructure. By the Essential Commodity Act Amendment earlier this was actually brought in to ensure that there is no hoarding and so on. So the consumers would also get the agricultural produce, whether it is cereals, pulses, oils, oil seeds and so on at affordable prices. Now those controls have been removed and even foreign players as well as big agribusinesses, it promotes hoarding in a way and also there is no control. There is no limits on how much they can keep. Finally the farmers empowerment and protection agreement of price assurance and farm services bill 2020 which is also being called the contract farming bill 2020. This bill basically allows the system of contract farming in India. However 86% of the farming community in the country owns less than 2 hectares of land. The policy of contract farming shifts the power balance away from the farmer to the company, especially when the land holdings are so small. The farmer will in effect become a land owning tenant acting in the interest of corporations. India has been going through an unrelenting agrarian crisis for the past many years now with rising number of farmers suicides every year. Farmers have led many major movements demanding an improvement in conditions. However these moves by the BJP government are in the opposite direction from what farmers want. With these changes which are happening where they are trying to paint a rosy picture that these big agribusinesses will pay higher prices to the farmers that kind of a campaign is being done that is not going to actually translate on the field. The small farmer would not have the bargaining power with these big companies and once they establish their monopolies they totally dictate the terms. Farmers have been demanding for the remunerated prices to be a legal right and for maximum procurement at these prices through the regulated market places. Farmers want freedom from debt instead the government is dismantling whatever protection mechanisms exist and so farmer organizations have been leading protest actions for the past few months against these anti-farmer legislations. They have burned these bills they have sent from Miranda to the prime minister and they have held rallies. September 25th has been declared national resistance day to continue these protest actions. The All India Kisan Sabha that is the All India Farmers Organization which is leading this struggle has issued the slogan what the parliament can do the streets can undo.


Good morning. We're doing OK, not that hungover, I hope. I think it's probably the most expensive hangover I've had in a while. Anyways, my name is Lynn Root. I am a staff engineer at Spotify. I've been at Spotify for nearly six years. But since the beginning of the year, I've been working on building machine learning infrastructure for really smart people that do digital signal processing and need to productionize that. It's pretty fun. So if anyone here uses Apache Beam or does streaming with data pipelines, I'd love to chat afterwards. I'm also Spotify's FOS Evangelis. I help a lot of teams with their projects and tools to get them open source under the Spotify GitHub organization. And lastly, I am one of the global leaders of Pi Ladies, which is a mentorship group for women and friends to help increase diversity in the Python community. I brought a lot of stickers with me, so if you want a Pi Lady sticker, confine me. One random clap, thank you. All right, so this is Jenda for today. It doesn't look it, but it's a bit jam-packed. I'm going to be covering some graceful shutdowns, exception handling, and threading, along with testing, debugging, and profiling. I'll use probably most of my time, if not all. So I won't take any questions, but we can go outside afterwards and talk. And this presentation is very code heavy, but don't worry, the slides, for everything, the full write-up and the code is at this link, and I'll show it again at the end. OK, so async.io, the concurrent Python programmers dream, that's the answer to everyone's asynchronous prayers, right? The async.io module has various layers of abstraction, allowing developers as much control as they need and are comfortable with. Simple hello world-like examples do show how it can be so simple, but it's easy to get lulled into a false sense of security. These sort of hello world examples aren't that helpful. We're led to believe that we can do a lot with the structured async and await API layer. Some tutorials, well, great for the developer to get their toes wet, try to illustrate real world examples, but are actually just beefed up hello world examples. Some tutorials even misuse the async.io interface, allowing one to easily fall into the depths of callback hell. And there are some tutorials that will get you easily up and running with async.io. But then you may not realize that it's not exactly correct or not what you want, or it only gets you part of the way there. And while some tutorials and walkthroughs do a lot to improve upon the basic hello world use case, maybe it's just still just a web crawler. I'm not sure about others, but I'm not really building web crawlers at Spotify. I've built services that do need to make a lot of HTTP requests, sure, and they need to be non-blocking. But these services online, they also have to react to PubSub events, to measure progress of actions initiated from those PubSub events, handle any incomplete actions or other external errors, deal with PubSub message lease management, and measure service level indicators and send metrics. And we need to do this with non-async.io friendly dependencies. So for me, my problem got difficult quickly. So allow me to provide you a real-world example that actually comes from the real world. Has anyone heard of Netflix's Chaos Monkey? I see some hands. So a few years ago at Spotify, we built something similar, like a chaos creating service that does periodic hard restarts of our entire fleet of instances. And so we're going to do the same here. We're going to build a service called Mayhem Mandrill, a pun-off Chaos Monkey, which we will listen for a PubSub message and restart a host based off of that message. And so as we build this service, I'll point out best practices that I may or may not have realized when first using async.io. And this will essentially become the type of resource that Paslin would have wanted about three years ago. And again, don't worry about the code in the slides. I'll have a link that refers to all the code at the end. So we're going to start with some foundational code. We're going to write a simple publisher. So here's where we're going to start. We have a while true loop. We have a unique ID for each message to publish to our queue. I want to highlight that we're not going to await the queue.put of a message. async.io.createTask will actually schedule a coroutine on the loop without blocking the rest of our for loop. The createTask method does return a task object, but we can also use it as sort of a fire and forget mechanism. If we added the await here, everything after this within the published coroutine will be blocked. This isn't an issue with our current setup, but it could be if we were to limit the size of our queue, then that await would be awaiting on space to free up in the queue. So we're just going to stick with the async.io.createTask. So we have a publisher coroutine function, and now we need a similar consumer. So this consumer will consume the messages that we've published that's sort of similar to the publisher. We have a while true loop and await on the queue for a message. But here we don't want to create a task of queue.get. It makes sense to block the rest of the coroutine because there isn't much to do if there are no messages to consume. I want to highlight this again. We're only blocking within the scope of the consume coroutine. We're not blocking the actual event loop. So let's replace async.io.sleep with a function that will restart a host. I'm sure it looks like I'm just like pushing the simulation of Iowork to the restart host function, but in doing so, I'm actually able to create a task out of it, so therefore we're not blocking and awaiting for more messages. Perhaps we want to do more than one thing per message. For example, in addition to restarting a host, maybe we'd like to store that message in the database for potential replaying later as well. So we'll make use of async.io.createTask again for the save coroutine to schedule on the loop, basically chucking it over to the loop to execute when it can. And in this example, the two tasks of restarting and saving don't need to depend on one another. I'm completely sidestepping the potential concern or complexity of should we restart a host if we can't save to the database and vice versa. But maybe you actually want your work to happen serially. You may not want to have concurrency for some asynchronous tasks. So for instance, maybe you restart hosts that have an uptime of more than seven days. So this is similar to like within banking, you should check the balance of an account before you actually debit it. So needing code to be serial or sequential to have steps or dependencies, it doesn't mean that you can't be asynchronous. The await last restart date will yield to the loop, but that doesn't mean that restart hosts will be the next thing that the loop executes. It will just allow other things to happen outside of this coroutine. So with that in mind, I will just put all this message related logic into a separate coroutine so we don't block the consumption of messages. Saving a message shouldn't block a restart, a host if needed, so we'll return to it being a task. And then we're just going to remove the uptime check and just restart hosts indiscriminately because why not? So we pulled the message from the queue and found out work based off of that message. And now we need to perform like finalization work on that message. And so often with PubSub technologies, if you don't acknowledge a message within a predefined timeframe, it will get redelivered. So for a finalization task, we should acknowledge the message so it isn't redelivered. We currently have two separate tasks, save and restart host. And we want to make sure that they are both done before the message is cleaned up. We could go back to the sequential awaits since that's a very direct way of manipulating the ordering. But we can also use a callbacks on a completed task. What we therefore want is somehow to have a task that wraps around the two coroutines of like save and restart host since we have to wait for both to finish before cleaning up can happen. We can make use of async.io.gather which returns a future like object to which we can attach the callback of cleanup via add done callback. We can now just await that future in order to kick off the save and restart host coroutines. And then obviously the callback of cleanup will be called once those two are done. And so visualizing this a bit, you can see that both the save and the restart coroutine are complete. And then the cleanup will be called to signify that the message is actually completely done. And we've also maintained appropriate concurrency. And I don't know about you, but I have an allergy to callbacks. So perhaps we also need cleanup to be non-blocking. And so then we can just actually await clean after awaiting gather itself, which I think is much cleaner looking. So to quickly review, async.io is pretty easy to use, but being easy to use doesn't automatically mean that you're using it correctly. You can't just throw around async and await keywords around blocking code, sort of a shift in a mental paradigm, both with then needing to think about what work can be farmed out and let us do its thing, and then what dependencies are there and where code might still need to be sequential. But having your steps within your code, like having first A, then B, and then C, may seem like it's blocking when it's not... Sequential code can still be asynchronous. For instance, I might have to call customer service for something and wait to be taken off hold for them. But while I wait, I can put the phone on speaker and pet my super-needy cat. So I might be single-throated as a person, but I can still multitask. So often, you'll want your service to gracefully shut down if it receives a signal of some sort, like cleaning up open database connections, stop consuming new messages, finish responding to current requests while not accepting any new requests, that kind of thing. So if we happen to restart an instance of our own service, we should probably clean up the mess that we've made before exiting completely out. So here's some typical boilerplate code to get service running. We have a queue instance, setting up the loop, scheduling the publish and the consume tasks, and then starting the event loop. Maybe you even catch the commonly known like keyword interrupt exception. So if we run it as is and then send it the int term or int single, we see that we do get to that accept and that finally block with these two log lines. However, if we send our program a signal other than SIGINT, like SIG term, we see that we don't actually reach that finally clause, where we're logging that we're closing up the loop. It should also be pointed out that even if you're to only ever expect a SIGINT signal or a keyword interrupt signal, it could happen outside of the catching of exception, potentially causing the service to end up in an incomplete or otherwise unknown state. So instead of catching keyword interrupt, we can use a signal handler on the loop itself. So first we define our shutdown behavior or a coroutine that will be responsible for doing all of our unnecessary shutdown tasks. Here I'm just like closing database connections, returning messages as not act so that they can be delivered and not dropped. And then cleaning up or collecting all outstanding tasks up for the shutdown task itself and then canceling them. Now we don't necessarily need to cancel pending tasks, we could just collect them and allow them to finish. We may also want to take this opportunity to flush any collected metrics so that they're not lost. So then let's add our shutdown coroutine function to the event loop. So the first thing we do is set up our loop first and then add our signal handler with the desired signals that we want to respond to and then remove the keyboard interrupt. So then running this again, we actually do see that we get to that finally clause. Now you might be wondering which signals to react to and apparently there is no standard. Basically you should be aware of how you're running your service and handle accordingly. It seems like it could get particularly messy with conflicting signals and when adding Docker to the mix. Another misleading API in Async.io is the shield method. And so the docs say that it's meant to shield a future from cancellation, but if you have a coroutine that must not be canceled during shutdown, async.io.shield will not help you. So this is because the task in async.io.shield creates like that task that gets created gets included in async.io.all tasks and therefore receives the cancellation signal on just like the rest of the tasks. So to help illustrate this a little bit, I have a simple like async function with a long sleep that then like finally logs a line saying done. And we had to shield it from cancellation. So as per the docs, we have like a parent coroutine shielding the coroutine to get canceled. And so the task that is running, the parent has is running the shielded coroutine. If that's canceled, it shouldn't affect the shielded coroutine. And so then we add our parent tasks to our main sort of function. And then when we're running this and interrupting it after a second, we see that we don't actually get to the done log line and that it's immediately canceled. Even if our shutdown coroutine function skips canceling the shielded coroutine or even the parent tasks, it still ends up getting canceled. So basically we don't really have any nurseries in async.io core to clean ourselves up. It is upon us to be responsible and close up connections and files that were open and respond to outstanding requests, basically leave things how we found them. Doing our cleanup in the finally clause isn't enough though, since a signal could be sent outside of the try accept clause. So as we construct our loop, we should tell how the loop should be deconstructed as soon as possible in the program to ensure that all of our bases are covered. We also want to be aware of when our program could be shut down, which is closely tied to how we run our program. If it's a manual script, then SIGN is fine, but if it's like a demonized, within a demonized Docker container, then SIGN term might be more appropriate. And then finally, if you use shield in a service that has a signal handler, you should be aware of its funky behavior. So you might have noticed that we're not doing any handling of exceptions so far. Let's revisit our RESTART host coroutine, and we're gonna add a super realistic exception. So running this, we do see that the super serious exception is raised. But we actually get a task exception was never retrieved. This is because we don't properly handle the result of the task when it raises. We can do is define sort of a global exception handler. This is super simple or super simplified. And then attach it to our loop, similar to signal handling. And so if we were to rerun this, we do see that logging of exception that we are actually handling that. But perhaps you want to treat exceptions more specifically from certain tasks. It's good to have exception handling on a global level, but also on a more specific level. So let's revisit our handle message coroutine. Say for instance, you're fine with just logging when a save message fails, but you want to knack or not acknowledge the PubSub message and put it back to the queue to retry the whole message if RESTART fails. So since async.io.gather returns results, we can add more of a fine grain exception handler to this and handle the results as we wish. I want to highlight that setting return exceptions to true is super imperative here. Otherwise exceptions will be handled by the default handler that is set. So be sure that there are some sort of exception handling either globally, individually, or a mix, most probably a mix. Otherwise exceptions may go unnoticed or cause weird behavior. I also personally like using async.io.gather because the order of return results are deterministic, but it's easy to get tripped up with it. By default, it will swallow exceptions, but happily continue working on other tasks that were given. If the exception is never returned, then weird behavior can happen. All right, sometimes you need to work with threads.  And you might want to consume a message on one thread and then handle the message within a coroutine on the main event loop. So let's first attempt to use the async.io API that we're familiar with and update our synchronous callback function with creating a task via async.io.create task from the handle message coroutine that we defined earlier. And then we call our threaded consume function via the thread pool executor, but we don't get very far. At this point, we're in another thread and there's no loop running on that thread. It's only on the main thread. So if we take what we have right now and update our function to use the main event loop, we actually do get it working or it looks like it worked, but this is deceptive. We're sort of lucky that it works. Some folks can probably already see that we're not being thread safe. So instead of loop.create task, we should be using async.io's thread safe API, the run coroutine thread safe. It can be difficult to tell when you're not being thread safe, particularly when it looks like it works as it did in our previous attempt, but in a bit, I'll actually show you how to easily surface when there's an issue of thread safety. So my opinion, it isn't too difficult to work with threaded code and async.io, or similarly to how we work with non-async code in the async world. We just make use of the thread pool executor, which essentially creates an awaitable for us. However, it's difficult to work with both threads and async.io when there's some sort of shared state between a thread and the main loop. And so if you must, then use the thread safe APIs that async.io gives you. It took me an embarrassingly long time to realize that this existed. All right, now on to testing. So for a more simplistic starting point, we're going to test async.io code before we introduce threading. So to start simple, we're gonna test the save coroutine using PyTest. Since save is a coroutine, our tests will need to run the coroutine in the event loop. So like so, which Python 3.7 makes it easy for us with async.io.run. Or with older Python 3.0 versions, we have to construct and deconstruct the loop yourself. But there is a better way. So there's a PyTest plugin called PyTest async.io that will essentially do that hard work for you. And then all you need to do is mark the particular tasks that are testing async code with a decorator from that plugin as well as make it so that the test function itself is actually a coroutine function. So now when running the test, the plugin will essentially do the work for you of constructing and deconstructing the event loop. The PyTest async.io plugin can get you pretty far, but it doesn't help you when you need to mock out coroutines. So for instance, our save coroutine function calls another coroutine function, the async.io.sleep, or maybe some actual call to the database. You don't actually want to wait for async.io.sleep to complete or you don't actually want a connection to the database to happen. So both the unittest.mock and the PyTest.mock libraries do not support asynchronous mocks. So we're gonna have to work around this a bit. So first, we do make use of the PyTest.mock library and we create a PyTest fixture that is essentially returning a function. The outer function itself returns the inner function as a fixture that we'll use in our tests. And then the inner function is basically creating and returning a mock object that we'll use in our test, as well as a stub coroutine that the mock will end up calling. It also patches, if needed, the coroutine function with the stub so we can avoid network calls, sleeps, et cetera. So then we're gonna create another PyTest fixture that will use the create coro mock fixture to mock and patch async.io.sleep. We don't need the stub coroutine that it returns so we can just essentially throw that away. And then we're gonna use the mocksleep fixture in our test save function. So what we've done here basically is patched async.io.sleep within our mayhem module with the stub coroutine function. Then we just assert that the mock to async.io.sleep object is called when mayhem.save is called. Because now we have a mock object instead of an actual coroutine and we can do anything that is supported with your standard mock objects like assert called once with setting return values and side effects. So it's pretty simple, I guess, ish, but maybe you want to test code that calls create task and we can't simply use the create coro mock fixture however with this. For instance, let's revisit our consume coroutine which creates and schedules a task on the loop out of handle message. We first need to create a couple of fixtures for the queue that gets passed in. First we'll mock and patch maysync.io queue class in our module. And then we'll use that mock queue fixture in another one, a mock you get fixture. So unlike our mock sleep fixture, we will use the stub coroutine that create coro mock returns and then set it to the mock queue get method. So here's our test consume function where we're giving our newly created fixtures. So let's try to use the create coro mock to mock and patch the call to handle message via coroutine via create task. Note that we're setting the mock get side effect to one real value and one exception to make sure that we're not permanently stuck in that while loop. And finally we want to assert that the mock for handle message has been called after our consume has been run. So when running this, we see that mock handle message is not actually called like we're expecting. And this is because the scheduled tasks are only scheduled at this point and impending and we sort of need to nudge them along. So we can do this by calling, collecting all running tasks but it's not the test itself and running them explicitly. This is a bit clunky, I know. If you use the unit test from standard library, there is a package called async test that handles this better and exhausts the scheduled tasks for you. So I hear that you're wanting like 100% test coverage which is great but it might be difficult for our main function. We need to set up signal handling and exception handling and we need to create a few tasks and then start and close the loop. We can't exactly use the event loop fixture that PyTest async.io library gives us as it is now. We need to sort of manipulate the event loop that PyTest async.io will use to when it injects it into the tested code. So what we do is update the testing event loop. We can override the close behavior. If we close the loop during the test, we will lose access to the exception and signal handlers that we set up within the main function. So we actually want to close the loop after we're done with the test. And then we can also use the mock to assert that our main function actually closes the loop. So now we'll write a test main function that actually borders on like an integration or functional test. We want to make sure that in addition to expecting calls to publish and consume, that shutdown gets called when expected. But we can't exactly mock out shutdown with a create co-row mock since it will patch it with just another coroutine and therefore run the mocked coroutine each time it receives a signal rather than canceling the tasks and stopping the loop. So instead, we're gonna mock out what's called with the shutdown coroutine, the async.io.gather. And then here I'm starting a thread that will actually send the process a signal after a 10th of a second. And so after the starting the thread, we then called main function that we want to test. So looking at the second half of the test, we can assert that the loop setup is the way that we expected as well as our mocked out functions having been called. Returning to the setup, the first half of the test, here you might want to parameterize the test function itself to test not just the sigint signal, but all the signals that we're expecting and probably test with a signal that you're not expecting like a sig user or something like that. So basically the TLDR of using is to use pytest async.io. There's also a package called async test for a unit test that functions similarly to a pytest async.io. And the bonus is that it will exhaust the task schedule on a loop for you automatically as well as provide coroutine mocks. So all right, we're a decent programmers and have code coverage, but sometimes ship breaks. We need to figure out what's going on. And we can use everyone's favorite debugger printing even if you want to admit it. So if you have like one tiny little thing to debug, you can use the print stack method on the instance. And so when you run this, it will print the stack for you for each running task. You can also increase the number of frames that are printed as well. But you probably will actually use, we'll need to use async.io's debug mode within the standard library itself. So along with setting our logging level to debug, we can easily turn on async.io's debug mode while we run our script. If we didn't have proper exception handling setup, we'd get information about which task is affected. And also what is called a source traceback that gives us more context in addition to like our normal traceback. So without debug mode, we get told that there's an exception that's not properly handled, but with debug mode, it gives us an additional clues as to what might be going on and where they might be. Another very handy thing that I wish I knew of a few years ago, is that if you have threads and event loop interacting with each other, debug mode will surface not being thread safe as a runtime error and just quit out. Super helpful.  So we can fake a curve routine by putting a blocking call to that with time.sleep. And so when we run the script, we can see that it will surface slow to finish tasks, potentially highlighting an unnecessarily blocking call. The default for what's considered slow is 100 milliseconds, but that is easily configurable too. You can set it directly on the loop with slow callback duration in seconds on the loop directly itself. So much like some people's testing philosophies, sometimes we wanna debug in production, because why not? But usually you don't want full on debug mode while in production. So there's this lightweight package called a.iodebug that will log slow callbacks for you. And it also comes with the ability to report delayed calls to a stats D if you use stats D. And so that's all what this library does. So it's super lightweight and quite handy. So you can easily print the stack of a task if needed, but you do get a lot with async.io's debug mode. It gives more information around unhandled exceptions when you're not being thread safe and when there are slow to complete tasks. And if you want to understand slow task while in production, a.iodebug is a lightweight library that essentially does only that. As we saw with async.iodebug mode, the event loop can already track coroutines that take up too much CPU time to execute, but it might be hard to tell when it's an anomaly or what is a pattern. So a lot of folks might first reach for a C profile when trying to understand performance. And we can try that here too. But there isn't that much to glean from this. The top item here is essentially the event loop itself. And even if we looked at our own code specifically, you can kind of get a picture of what's going on, but it doesn't immediately surface any bottlenecks or particularly slow areas. Of course, our main function would have the most time cumulatively since that's where the event loop is ran, but nothing is immediately obvious. So I recently discovered Kcash Grime, even though it's been around for a while, but you can use it with Python. And to do so, we first save the output of C profile and then use this package called PyPROF2Cultry, which takes the output of C profile and converts the data into something that Kcash Grime can understand. And so when the script is ran, you're met with this UI, and it's okay if you can't make anything out, but basically on the left-hand side, there's a profiling data that we would otherwise see from the output of C profile. And then the two sections on the right shows information about collars and collies, including a call graph, which is on the bottom and a map of the collies, which is on the top. If we limit our view to only our script and start clicking around, we can start to get an idea of where time is most spent. The visualization groups modules together by color. And so when I first ran the service, I noticed there's a lot of blue on the collie map that's on the top there. And if you click into that blue, it's actually logging that's taking a lot of time. I'm gonna go back to that point in a second. So Kcash Grime allows us to get a broad picture of what's going on and gives us visual clues of where to look for potential areas of unnecessary time spent. But then there's the line profiler package, and we can use it to hone in on areas of our code that we're suspicious of. So after installing the profiler, you can add a profile decorator where you want to profile. Here I'm just decorating the save care routine for now. The line profiler library comes with a tool called KernProf that we will invoke our script with, and then we render the output of line profiler itself. And this is a line-by-line assessment of our decorated code. The total time spent in this function is just over two milliseconds, and the majority of that time was spent in logging. Now, if only there was something we can do about that. Coincidentally, someone has done something about it. There's a package called AIOLogger that allows for non-blocking logging. So if we switch that to default logger with AIOLogger in rerun line profiler, we can see that our total time spent in that function has halved, as well as time spent while logging. So certainly these are like minuscule improvements that we're doing here, and there's probably a lot more that we can do. But if you imagine this sort of on a larger scale, we could probably save a lot of time. And also as I see it, if we have an event loop, let's try and take full advantage of it. So we've profiled using Cprofiler and line profiler, but we had to stop the service in order to look at results. So perhaps you'd like a live profiler along with your production testing and debugging, if you do that. Now, there's a package called profiling that provides an interactive UI, and it supports async.io, as well as threads and greenlets. And granted, you can't attach to an already running process with this particular tool. You'll need to launch your service with it. And when you do, you get this text-based UI that regularly updates. You can drill down, you can pause it while inspecting something and restart it. You're able to save performance data to view it with this UI at a later time, and also provides, the tool provides a server, which you can then remotely connect to it. So the TLDR of profiling, there isn't much difference with profiling async.io code from one async.io code. It can be a little confusing though with looking at C-profile output to get an initial picture of your service's performance. Using a C-profiler with Kcash Grine can help surface areas to investigate. Without that visualization, we saw that it can be a bit difficult to see the hotspots. Once you have an idea of those hotspot areas, you can use a line profiler to get a line-by-line performance data. And finally, if you want to profile in production, I suggest taking a look at the profiling package. So in essence, this talk is something that I would have liked a year ago, speaking to Pasalyn here, but I'm hoping that there are others who can benefit from a use case that is not a web crawler. This is the link to a full blog post, the slides and all the code, and I must give my obligatory spiel where Spotify is hiring for various engineering and data science positions at all of our engineering offices, Stockholm, London, New York and Boston. So if you're interested, you can come talk to me. And thank you very much.


After a near two week hiatus, the first break of the season, the 15th ranked BSU men's hockey team is back in action this weekend. The Beavers travel to Alaska Anchorage for a conference series to open the second half of their schedule. BSU is 13-1-2 in conference play this season, owning 43 points and a 6-point lead in the WCHA. And they'll look to extend that this weekend. We've been pretty good on the road and you know obviously you look at your road record so you know you're confident but you also realize again how difficult it is with the travel and again it's not only two games it's four games so we'll see but again that's just the way the schedule is and again we had a tough first half we played a lot of games and you know we had some success so again you just hope that all that stuff just carries over. If you've enjoyed this segment of Lakeland News please consider making a tax deductible contribution to Lakeland Public Television.


Good morning, everyone. And thank you so much for tuning in today to the monthly animal science webinar today I'm gonna talk about using poultry litter in pastures and hayfields There are several topics that I'm gonna gonna cover today So some of the items that I'm gonna cover today is what exactly is poultry litter what it is made up of, okay? What are the benefits of litter application and then I'm gonna also discuss about the risk associated with poultry litter and Finally, I'm gonna provide a quick update on some of the research which my lab group and my students have been doing So we are I'm gonna talk about the nutrient release characteristics of different types of poultry litter So let's get started first first thing first. What is poultry litter? So poultry litter is actually a mixture of fishies, spilled feed, water, feathers and bedding materials and Of course, there are different kinds of bedding materials that are used in Chicken houses some of the common ones are peanut hulls, pine shavings or chips and One thing to remember is that the carbon to nitrogen ratios of these different kinds of bedding materials change and You know, they're very different actually and say for example, wood chips will have a much higher carbon to nitrogen ratio And and carbon to nitrogen ratio is important because you know It tells us that how fast or slow that particular material can decompose So if the carbon to nitrogen ratio of a particular bedding material is high, it will decompose slowly The other important aspect of having a bedding material is typically to kind of like facilitate the quick drying of the bird droppings and You know keeping the moisture to a really low level Now let's talk about what exactly is Chemical composition or what is the chemical composition of poultry fishes or chicken fishes? So chemically the bird dropping is You know, it is it's comprised of uric acid urea ammonia creatine and undigested proteins But majority is actually uric acid almost 70% of the bird dropping is actually composed of uric acid But this uric acid is very unstable and it quickly gets converted into urea and then urea gets quickly converted into ammonia Now once it's in once ammonia is formed it will have two Fits either it will virtualize or it will go through a nitrification process where the ammonia gets converted into ammonium and Ammonium eventually gets converted into nitrate which are the plant which which is mostly the plant Available for form So now let's talk about the benefits of poultry litter application in pasture fields or in row crop fields So there are multiple the very first one is helps to improve the soil ornate matter You know and of course it also increases the microbial activity It helps to build the soil structure That's really important especially, you know here in Alabama where we have really eroded soils So it helps to build the soil structure and keeps the soil in place and that also helps to prevent solely rosin or reduces the solely rosin and One of the major benefits of poultry litter is it saves money on costly fertilizers and We will take a look at that. What is the fertilizer value of poultry litter? So We all know that poultry litter. It has three main Nutrients from a plant nutrition standpoint, which are which are nitrogen phosphorus and potassium So let's first calculate the nitrogen value of poultry litter. Okay, so today, you know Urea I mean most most the most common source of nitrogen is urea So the current prices of urea is around 47 cents per pound of nitrogen one ton of chicken litter has 60 units or 60 pounds of nitrogen Therefore one ton of litter has a fertilizer value of around $28 and 20 cents. Okay Now let's calculate the Potassium value of a broiler litter. So Most common source again for potassium is pot ash or murid of potas the current prices of murid of potas is around 25 cents per pound and One ton of litter has around 40 pounds of phosphorus 40 40 pounds of pot ash therefore one ton of litter Has a potassium value of around $10. So Now let's look into the phosphorus. Okay, so the so say for example, you know We can calculate the phosphorus value based on the triple super phosphate Prices so the current price of super phosphate is around 40 cents per pound and One ton of broiler litter has 60 units of phosphorus Therefore one ton of litter has a fertilizer value or the phosphorus fertilizer value of around $24 So summing up together $28 for nitrogen $10 for Potassium and $24 for phosphorus. So the total Value the total nutrient value of one ton of poultry litter is $62 and 20 cents But wait a minute Most people will argue that not all of the nutrients are available during the first year So let's make some assumptions Let's say that 50% of the total nitrogen is available in year one 50% of phosphorus is available in year one And then 85 85% of potassium is available in year one and the remaining which we call as the residual Nutrients, they may be available in year two three or consecutive years So let's look or calculate the fertilizer value by using these percentages So when we do that we see that If we account for only 50% of nitrogen that is available in the year first that Translates into $14 and 10 cents as a nitrogen value for phosphorus It's $5 and for potassium. It's $20. So the the total fertilizer value of poultry litter is around $39 and 50 cents in year one But you also remember but do remember that you know the nutrient the poultry litter does supply other micronutrients such as boron, copper, zinc and manganese Which we did not accounted for in this calculation Besides, you know, you know most of the research States that commercial fertilizers are 50% efficient or the end uptake The nitrogen uptake efficiency is only 50% So this means that rest of that is lost. So just from a comparison standpoint we can think that We can compare these two different kinds of fertilizer, but of course, you know litter has Not it did not only provides nitrogen phosphorus and potassium, but also supplies or it's a source of Boron, copper, zinc and manganese Now let's talk about the risks associated with the use of poultry litter as a fertilizer And of course, there are several risks just like any other manure The most important risk that comes from litter application is through pathogens. We are Which are salmonella and E coli The other important risk. I'll not say it as a risk, but of course, you know It's it's a challenge is the order, you know Litter application has the order issue and then You know, it can create conditions of complaints from neighbors and so of course that is considered as a challenge and one of the other challenge is The repeated application of litter over several years lead to build up a phosphorus in the soils and which can turn into Environmental situations of water quality which can bring water quality problems. So these are some of the risks that are associated with poultry litter use as a fertilizer But I'm gonna today talk or focus mostly on the nutrient buildup, especially the phosphorus buildup So many people can think that okay So tell me how phosphorus application leads to build up of phosphorus in the soil so say for example, you are a bird manure grass hay grower and Your average yield is around six tons per acre The nitrogen requirements for a six ton Six ton of bird manure grass hay is around 300 pounds of nitrogen so and You know, we all know that a ton of litter has 60 pounds of nitrogen. So if you are putting Or me if you want to meet the nitrogen requirements of your hay production You'll have to apply five tons of poultry litter So if we apply five tons of poultry litter, of course, you're applying 300 pounds of nitrogen 300 pounds of phosphorus and 200 pounds of potassium We also need to know that the bermura grass hay removes only 12 pounds of phosphorus per ton So for a six ton But more grass hay the total removal would be 72 pounds of phosphorus All right, so now let's look look look up at the mats here So we applied 300 pounds of phosphorus, right for six tons of bermura grass hay and The total plant removal or uptake was 72 pounds So when you do the mats the balance is around 228 pounds of phosphorus So that amount of phosphorus stays behind in year one through application of five tons of chicken litter and if somebody is Raising bermura grass year after year after year and has been applying poultry litter every single year at the rate of five tons guess what? If the soil fall Previously in a medium fertility It will take four or five years for that soil to reach to a high fertility level and And we all know that when the soil reaches a high fertility level or when it's high for phosphorus You don't get any ill benefits This means at that point, you know once your souls reach to a high fertility level for phosphorus There is no benefit of adding any phosphorus or ill benefit because of the phosphorus but when the phosphorus builds up in the soil, you know, it's a challenge and It can create several environmental issues, especially You know the water quality issues. So let's let me first talk about, you know, what are the modes through which? phosphorus can get into the water so Phosphorus can get into the water through three different pathways. The first one is called is erosion when soils Kind of you see like soil coming out from your field in runoff water as sediments that's the Phosphorus is tied to the sediments and it comes out of your field via erosion The next category is of the next category for phosphorus transport is runoff So phosphorus is very reactive. It gets dissolved in water pretty quickly And when there is like severe weather and extreme rainfall events and you see like water leaving your property Or fuel and going into the creek That's where this reactive phosphorus gets into the water system. The third Important mode of mechanism of phosphorus transport water is through leaching and this happens typically in sandy soils where phosphorus moves vertically downwards and especially when there is a Water table, which is really shallow or like, you know, you know The phosphorus can get into that water and can contaminate the entire ground water For several years So these are the three common transports. So one of the questions that has been asked repeatedly like so tell me how can we minimize this excessive buildup of phosphorus in the soil and The answer to this question is you need to constantly monitor your soil test phosphorus levels You know Because that's the only way to know whether you are running into the danger zone of having a high phosphorus And if you if you see that your soil test levels are really high for phosphorus It's always a good idea to stop applying litter for a few years and then supply The nitrogen and potassium demands using the commercial fertilizer. So or Alternatively, you can rotate between your commercial fertilizer and Your poultry litter and this this way it will delay or actually reduce the risk of phosphorus loss into the environment Next I will talk about The research that we have been doing in our lab and this is research for from one of my graduate student who is studying the release characteristic of phosphorus, but also different nutrients So in her work We we collected different poultry litter samples and we classified in them into three different Categories the first category is the fresh litter The second one is the cake litter and the third one is called as composted or aged litter So fresh litter is the litter that is Collected after six months or probably like, you know after four or five Flocks, you know when the growers clean out their houses So that's the kind of litter which we are calling it as fresh litter Then the other category is cake litter which where you know Growers remove or de cake After two years and then then remove it. So that is the de cake litter cake litter And the third category is the compost where the litter has been stored in the pile for a couple of years It stays there and is undergoing the natural composting process. So that's what we call it as the age litter So we are studying the Phosphorus and other nutrient release characteristic of these three different kinds of litter So let me provide you a brief Background about what are the different kinds or forms of phosphorus that are present in any poultry litter So, you know, in Paul whenever we send a poultry litter samples We always get the total phosphorus analysis, but total phosphorus analysis is actually comprised of several different categories of four or forms of phosphorus and The important forms are there are three important forms one is called as dissolved reactive phosphorus DRP and These are like mostly plant available phosphorus, you know, like orthophosphorous Or pyro or meta phosphates the second form of phosphorus that is present in litter is called as dissolved Non-reactive phosphorus. So this form of phosphorus is not accessible by the plants, but it is accessible to the microbes and Microbes can break these when they need them and and some of the common dissolved forms of non-reactive phosphorus lipids or DNA or RNAs Which are out, you know in the environment in the natural soil solution Then the third part is It's called as the recalcitrant organic phosphorus and these form or pool of phosphorus is very hard to break I mean, it takes a quite a bit of energy by the microbes to break these and it's very slow to become So very slow to degrade or decompose So most of the phosphorus that is available to plants is the dissolved reactive P and the dissolved non-reactive P whereas the recalcitrant phosphorus is a very Stable kind of phosphorus that stays in the soil for a long period of time. So for in this particular experiment we studied the Release characteristic of these three different forms. So the most important form is the dissolved reactive phosphorus, okay? So again a little bit about a background about our materials and methods So we collected these different kinds of litter from houses poultry houses in different parts of the state in Alabama And then we conducted a wasp experiment in the laboratory where we watched we did a repeated extraction of phosphorus from this poultry litter and then we analyzed it for All these three different categories which were the reactive the dissolved reactive the dissolved non reactive and the recalcitrant organic P So let's first we can also think about, you know about, you know, say for example a producer applies poultry litter, okay? And when there is a series of rainfall, especially like when we enter into the winter month, you know, we see like A series of rainfall events. So say for example a farmer applied poultry litter and then the first and after he applies We got the first rain. So how much phosphorus can we expect that? You know that will be released from the poultry litter Then also how much phosphorus can we expect that would be released during the second rainfall event and third and fourth And so on and so forth So that's how we are trying to mimic this or trying to understand the release rates of different kinds of phosphorus under different rainfall events So this is a graph that tells the release characteristic of the dissolved reactive phosphorus remember, I just mentioned that the dissolved reactive phosphorus is the phosphorus form which is readily available or accessible to the plants so And we are comparing and contrasting the release rates of these three different kinds of poultry litter, one is six months old litter, the cake litter and the compost litter What we see here, a very interesting finding here is that the release rates of the release rate of phosphorus differs between these three kinds of litter and and Actually, the cake litter releases the most dissolved reactive phosphorus in the first wash cycle or the first rainfall event Compared to the six months old litter or a composted litter The other important thing to note is like this release rate follows Exponential decay order meaning that initially it releases the phosphorus fast and as We move on or as with subsequent rainfall events This release rates decrease down or slows down considerably So most of the phosphorus as you can see is released during the first second third and fourth Rainfall events or wash cycles after fourth, you know The amount as well as the release rate decreases down considerably So now let's look into the percentages Let's talk in terms of percentage of like how much of the reactive phosphorus was released compared to the total phosphorus content In the litter. So what we see here is in the first wash cycle or first rainfall event Six months old litter released 14 percent of the total P as the plant up level or the dissolved reactive P Whereas compost litter they release 21 percent of the total phosphorus amount And then I'm sorry, excuse me the one two three year old or cake litter release 21 percent Whereas compost release 12 percent of Of the total phosphorus as a dissolved reactive P An interesting feature is that of course the cake litter has the highest amount of Phosphorus that is released during the first wash cycle or first rainfall event and as we go And then with consecutive wash cycles or rainfall event You can see here that these percentages drop down But the significant drop happens after the fourth cycle. So basically, you know after the fourth rainfall event You know only one point six eight or one point or one percent of phosphorus is released as dissolved reactive P or out of the total phosphorus The same same principle applies to the six months old litter as well You can see here that the percentage of the reactive P falls down Significantly and especially after fourth cycle. There is not much phosphorus or just Very less amount of phosphorus that is released after the first rainfall event We also looked into the distribution of different P forms So remember like we classified our total phosphorus into a dissolved reactive phosphorus dissolved non reactive phosphorus and Then the recalcitrant phosphorus or the residual phosphorus, which is very difficult to break down What we observed here is that in lit the composed Sorry that the cake litter, you know, 46 percent of the nitrogen is Present as a reactive phosphorus whereas 54 percent is present as as Recalcitrant organic Phosphorus but in six months old litter We are getting less of the total reactive phosphorus and more of a residual phosphorus of recalcitrant phosphorus and Same principle applies to compost. So it's quite You know, you can imagine that out of the total phosphorus only 46 percent gets released and is available to the plant You know, whereas the remaining like 54 percent is Not available to the plants and it's actually not even and it's very hard to degrade or decompose them so The rule of thumb here is like whatever the phosphorus Percentage is almost like 40 to 45 percent is only the reactive phosphorus that would be available to the plants Whereas the rest is a recalcitrant form and that will not be available to the plants and It's very hard to degrade them as well Now let's talk about the potassium release characteristics of litter and potassium release is very different than phosphorus In potassium what we observe is that most of the potassium is released right after the first rainfall or first wash cycle But after second you don't see any action basically So most of the potassium is released after the first rainfall and second rainfall events Third and fourth you don't see any or very little amount of potassium That would be released from poultry litter that tells me that potassium is present in a highly dissolved state and it easily gets it's easily released after the rainfall event and Of course, we see the differences as well Most of the potassium is is released Or a higher amount of potassium is released from a cake litter Whereas the compost releases the least amount of potassium So this is very interesting here that the amount of potassium that is present in Composed or a aged litter is very low compared to a fresh litter or like a cake litter and Their release rates are also very low Now the other question is what are the other nutrients besides phosphorus and potassium that gets released during these rainfall events and we found that some of the major Nutrients are sulfur, magnesium, calcium and aluminum But sulfur is the one that is released at the highest rate among all these three different litter types The next one is the magnesium and again You know, it's so important especially in in pasture fields because you know, we often think about the magnesium tetanus situation But poultry litter application and rainfall does help to actually release magnesium In the soil solution and that is a little bit of plants And yeah, so so so looking at all these different release rates of Nutrients it really helps us to think about the timing of litter application because You apply the litter and if it rains the next day and you haven't planted your crop or the forage is not growing You know all the nutrients that is released after the first rainfall basically is lost So it's very important to time the litter application And and you know again the percentage of nitrogen phosphorus and potassium That will be utilized by the forage In the first year will basically depend on the type of pasture that is present I mean, is it the cool season pasture or is it a warm season grass? Okay, I mean This is a chart that tells you the relative growth rate of a winter annual or a cool season or perennial Grass warm season perennial grass So it makes us think that if you are growing a cool season perennial grass and the maximum peak or the peak biomass production is between April and May we should time over litter application sometimes between between You know early January or like early sorry late January Mid-January to early February time period so that we can match the demand here For the cool season, but again like there are two cycles here You know, I mean we see a little bit of growth again back from October number time period So we can consider a second application probably here in the August timeframe When it comes to warm season perennial grasses I feel like the best timing of application is March to early April March to an early April time period because that's the time period when the plant demand in trees is So I believe like, you know, if we time over little application close to March or April you know and You know, there will be a better utilization of the new friends that is Released but again keep in mind. We have to also think about, you know, the rainfall events and you know in context of when the litter was applied and when the rainfall So all these things go into the decision of like when to apply Little so with that I like to thank you for your time and you know, I hope that you have learned something new about the The way the litter releases new trends And of course we post some of these interesting topics time to time at our Facebook page So do check us out at this Facebook link and thank you all for being here today


about a range of coding but the history of error detection and correction and how that led to a range of coding So thank you for coming And it's not working anymore one second, okay, there we go nice cool, so Who am I so my name is Danny and I work for a soft time in the UK where we're working on building a self-appliance I've mainly worked for Open-source companies in the past so companies like Lin bit and code link and I run a nonprofit in the UK called open source events Where we do tech meetups and conferences mainly around open stack and cloud native And yeah, I like beer So I mainly got interested in this topic a few years ago after I saw a colleague called Jim MacArthur do a lightning talk on error correction and So I wondered how this relates to raid and other storage technologies and I did some digging it figured out There's lots of ways to do this and I thought I'd provide an overview of some of the ways that Error correction and detection is done so the main idea is to have a set of techniques so that when we're transmitting data we can figure out if once we've received the data on the other end it's inconsistent or Even better if we can correct the data Rather than just dropping it. So these concepts have been around since before modern computers were born But they've come a long way. So even the older ideas are still around in some of our modern technology So why do we have errors in the first place? It could be human error. It could be network glitches. It could be something more random such as noise on a chip or Cosmic rays interfering with the chip all these things can Cause us to receive something different or the data to send something different So by a show of hands, how many people have heard of a parity bit? Pretty much the whole room cool So the parity bit is the earliest and most basic form of error detection in computers And it's a very basic type of checksum And the idea is that you can add a bit to the end of a set of bits Which let you detect an error when you transmit the data so we do this by adding up the number of one bits we have and If it's an even parity bit then we make it true for an even number of one bits And if it's an odd parity bit we'd make it true for an odd number of bits So you can see here that in the first Character we have two one bits that we're transmitting so because that's even we'll add a one on the end And we'll send that and if we receive the same thing on the other side We know that no error has transmitted Same again with K an even number of bits so we add a one on the end That's the one in bold and if we transmit it and there's an error or there's a different number We can do the calculation on the other side and see that actually we should have a zero There's obviously some sort of mistake So we just drop that frame and ask the whoever's whatever sent it to retransmit it And same again on the third one. There's another error there and that's an odd number of bits That's why the last the last bit that we're transmitting is a zero so this concept goes back as far as the 50s and We had parity tracks appear on mechanical tape drives in the early 50s the major flaw with this is that If you have more than one error within a byte, we're not going to detect it So it will only pick up One bit error surface multiple bits within the same segment then obviously it's going to be a false positive It's still very useful though, and we use it quite heavily in hardware applications such as microprocessor caches the PCI and scuzzy bus standards and RS 232 serial and lots of lots of other hardware applications use it So that's a very simple way to detect basic errors in transmission, but we can't correct them There's a decimal equivalent to this And this is used in lots of different real-world applications like social security cards ID cards and all major credit cards so this is one of my old credit cards or debit cards and You'll see that the last digit is actually a check digit. So how does this work? I don't know if you've ever noticed that when you're putting your credit card or debit card number into a web form It might automatically know Whether that's valid or not even if you're not connected to the Wi-Fi. It's all happening locally And that's due to this loon algorithm. And so the idea is this guy German-american engineer worked for IBM in the 40s and 50s And he was the first guy that came up with the idea of information buckets to speed up data retrieval and storage and The idea here is that that he came up with with this algorithm is that you double every digit every other digit starting from The right and then some all the digits and they should be a multiple of 10 And if they're not then you know that something's wrong So the last the last digit will either make it a multiple 10 or won't cool, so then we get on to trying to do some correction and The mate one of the main pioneers here is a guy called Richard hamming and he used to he was a mathematician and professor who worked at Los Alamos on the Manhattan project in 1945 and he was on a team which was responsible for programming the IBM calculating machines which had the scientist formulas check that they were correct and A few years later he went on to join Bell Labs And he became known to be one of the young Turks who was a group of people at Bell Labs that all Had heavy contributions to compute science They were all pretty well respected and they didn't have they weren't given the usual responsibilities and structure you know, but measured by grants and teaching teaching and papers they were kind of just left to get on with it and Three of them ended up going on to win Nobel Prizes and a few of them went on to lead Bell Labs But all of them are highly respected Scientists John Tukey was one of the first guys to come up with the name that the term bit which is contracted from binary information digit So while he was a Bell Richard hamming set one of his calculating machines to work on a problem over the weekend He said he said it on Friday and when he came back on Monday, he discovered that due to an error The whole calculation died early on Saturday morning And so he'd have to restart the whole thing again waste two days of work or wait till the next weekend And this was quite common because you had punch cards And so if a car was bent or it didn't punch properly then you know, you're gonna have an error so He then basically went on to perform probably the biggest yak shave in history and decided to sack off all that physics Nonsense and figure out how to get calculating machines to detect errors and automatically retransmit data identified as inconsistent so he published this key paper in 1950 called error detecting and error correcting codes and He described a few concepts that are still core to error detection and correction today and these are Number one is the hamming distance, which just describes how many single bit operations I have to do to correct a Binary number of string. So, you know for foster 19 foster 20. There's two characters different. That would be two But obviously on a binary level This can also be represented geometrically and it's called the hamming cube so he went on to define a system called the hamming codes, which is far more robust at checking errors than standard parity and What he developed was the concept of having three parity bits for every four data bits Which is quite expensive But it means that we can detect errors up to two bits and also correct one bit errors. So how does this work? Let's have a look. So if we have four bits here d1 to d4 and We want to send them over some sort of transmission channel. We can arrange them at the intersection of three circles so 1010 and Then we can calculate the parity for each circle. So For the parity circle one we have one one bit. So that's an odd number. So the parity will be zero for parity For the second circle, we have two one bits. So that's even so parties can be one For the third circle we have again one parity bit So that's odd. So that's gonna be zero. So we have three parity bits We add them to our data and we send that across the channel Now on the other side, we receive something different. So we get it d3 is turned to a zero instead of a one So how do we detect this? In the new circle that we're arranging on the other side You'll see that d3 switches to zero and then we'll recalculate starting with the first parity circle Nothing's changed there. It's still an odd number Something has changed there. It's now Supposed to be an even number of bits, but it's not a one bits, but it's not and the same for paratical three So we know that the offending bit is at the intersection of the second and third circles So therefore it's d3 and so we can just switch flip that bit and correct the error So that's the basic way that hamming codes work So We use parity pretty heavily in rage some of you'll be familiar with rate levels You probably you probably haven't come across rate two because nobody uses it and that's because it's really expensive But this is hamming codes and it happens at the bit level and so you can see that there's four data blocks and three Parity data bits are in three parity bits for on There are striped across these hard drives See I don't think anyone uses this Then you have obviously I'm sure all of you familiar with rate five rate four is similar to rate five There's the only difference is that rather than distributing the parity bits across the drives We put all the parity bits on one drive and that means that writes are slower with rate four since there's less data drives to write to you But since all the parity is written to the same disk Random reads are better Sorry, so writes are slower because the parity has to be written to the same disc But random reads are better because there's less disc for you to look for because you have a dedicated parity disc so That's that's read for this is read five and You're all familiar with rate five. I guess the way it works is it runs an exclusive or on the block. So for every two Blocks that we write we run an exclusive or and then we write the result as a third block And so green here is the is the parity data So if I keep doing that and obviously on different drives, I end up with a whole bunch of data Now if I lose one of the drives, I can recalculate it. It's just it's really simple Just run exclusive or again on the other two Data blocks and I can regenerate that drive So that's our rate five works So that's Hamming codes that was in the 50s then these guys guys came along in the 60s and they changed everything Good staff Solomon and Irving Reed and these guys were staff members at the MIT laboratory and Ten years after Hamming's paper. They published a paper called polynomial codes over a certain finite fields So I was reading up on this and I suddenly realized that this was getting really mathematically complicated I'm not a mathematician. I was out of my depth. So as I always do when I'm out of my depth I Go into IRC and ask a question. So I did that I went looking for the right IRC channel to think to ask in thinking that This would be helpful. I knew there was a bunch of mathematicians on this channel. So I just Just asked, you know, couldn't someone explain polynomial interpolation to me This is the response that I got I don't know maybe some of you understand what that I have no idea but yeah, yeah, I I Need to stop going to IRC for as a resource The main idea behind Reed Solomon does however revolve around this concept of a Galois field Galois field it's named after every Galois who was a French mathematician and unlike our previous heroes had a much more Troubled and interesting life in the sense that he got interested in maths at the age of 14 He published a number of papers by the age of 17 of which one of them was about Galois fields and Galois theory And this was a year after he was rejected from University because his examiner couldn't follow his train of thought and was very confused He was politically active ended up in prison a number of times before he Engaged in a duel to the death with an officer at the age of 20 and died. So not the most glamorous of stories, but Yeah, he did define this concept called Galois field, which is basically a mathematical field a set of numbers Which you can conduct mathematical operations on and a finite field or Galois field is one that is finite And it's always a size of a prime number or prime power And these fields wrap around so you can conduct any operation on the values within the field and always get another value in the field And you do this you can just modular the size of the field Once you get your results. So this can contain numbers it can contain polynomials and it contain roots of part polynomials And how does this relate to a rage coding and error correction? Well The idea is that using a Galois field you can essentially plot Any sequence of data as points on a polynomial graph And that's because the graph itself is representative of the Galois field that you're using Once you've done that you can then find other points on the graph which you can use as parity data So the purple ones are other points that we found on the same graph And that's what we will use as our code charts and the idea is that you define a code and you use that on both sides to recover data and it's highly efficient but Much more computationally expensive So here's an example K is the number of Data charts that we have M is a number of code charts on the left We have what's called a distribution or generator matrix, which is made up of an identity matrix at the top Which is essentially is equivalent to one and then the bottom piece is the Code charts which we generate So we add them together and we multiply that by our data and we end up with a set of data and a set of parity blocks so Let's say we lose some of our data the bit in K We can replace those with C1 and C2 Which are what we what we ended up calculating and we can Multiply that by the inverse of the same generator matrix that we have and that will give us our data blocks back And obviously that's far more efficient than using something like The hamming codes So this is really really popular. It's one of the most popular error correction codes We use today and it's it's seen everywhere including CDs DVDs You can it's using 2d barcodes as well So any any 2d barcode that you scratch or is damaged can still scan because it's using reach Solomon to recover from That damage and it's also used for generating qr codes So most implementations of rate 6 also use reach Solomon as well so this image is taken from the Rage coding docs in Seth and it's specifically for K equals 3 and M equals 2 So two parity shards for every three dates shards So in Seth when you create a new pool You specify if you want it to be a rage coded or not and also which rage coding algorithm you want to use Seth has a pluggable architecture for a rage codes So you can specify which code you want to use on a pool by pool basis once you've chosen an Arrange code you can't then change it for that pool because you'd have to obviously recalculate everything so You need to make sure the only way to do the only way to get around that You'd have to create another pool and migrate So if you're going to use an Arrange code a cooling product pool in production You want to be sure that you've chosen the rage code the best suits your workload Almost all of the rage coding plugins within Seth rely on some form of reach Solomon There's a number of different varieties though with different strengths and weaknesses the main plug-in that's used in Seth is called J-Rajor and that has both Vandermonde and Couchy versions that those are both versions of Reed Solomon and they they differ just in how you generate the the matrix at the beginning There's also some more recent propositions There's one called the shingle the rage code and that aims to be more configurable and more efficient There's also an implementation called clay which focuses on reducing network bandwidth and there's one called locally repairable codes which Specifies a another variable called L. So you can say I want my parity blocks to be stored in a specific geo location Which helps us recover? From a range of erasure coding damage, but without straining the network too much if we have a geo-replicated multi-size self-cluster So yeah, the key thing to remember is choose the right numbers for KNM obviously depending on how much storage you want to use how much is going to cost you in storage and Also pick the right Erasure coding plug-in once you've done some testing With your workload. So you you know that obviously it's a it's a kind of more final choice So how does this relate to our work at Softiron? Well, we're working on building stuff appliances and there's lots of operations that we want to do in stuff Which are computationally expensive compression of age coding and encryption are all examples of this So we're working on defining some of these algorithms and hardware so that we can use FPGAs to do the heavy lifting for us and Keep keep our CPU usage to just just staff So yeah, that's that's my talk How many questions no mathematicians in the room, I guess So I think that the most commonly so the question is what combinations of KNM are best and how do they Effect performance within staff So typically we see people using six K and and three for M or Nine and four those are the most commonly used ones We're only implementing a few different combinations on our FPGAs for that exact reason because That each one is going to be different how you define it in hardware so I think there's a standard set that are used and Yes, if you try and do it with less M then you're going to have to do it's going to be much more expensive to calculate the number of M as a proportion So you want to use a ratio of about three to one. I think I imagine there's network latency Yes, there is late network latency so There is heavy network latency in SAF and that means that also the question is how does it affect? How does the distributed nature of SAF? affect acceleration So there is network latency in SAF and that means that in some cases the The cost of going to recover the data in time might be Still far less than the the expense of doing the replication of the network anyway So you kind of have to have a bit of a cost balance and figure out in which cases it might be worth not Accelerating the process in which cases it might be worth accelerating so it It's a trade-off and I think in some cases it is some cases It isn't and that's a very important factor in deciding whether or not to accelerate Does that answer your question? cool Okay. Well, thank you very much


So there's a saying that a hero is only as good as his villain. And in the case of One Piece, some of the best and most memorable arcs include a good bad guy. As a long-running series, Luffy and his crew have faced a number of villains, some that make you scratch your head, although undeniably providing good comedic entertainment, while others are just plain polarizing. The story goes like this, we enter a new arc, we meet the villain, this villain has evil plans, our hero tries to stop said villain and his or her evil plan, resulting in some sort of combat, and then more recently, just before the culmination of the big fight, we get hit with a backstory. Now a backstory isn't super necessary to make a villain stand out, but it certainly provides much appreciated depth to what are usually already interesting characters. And we've come to expect this backstory because it serves as the final piece of the puzzle for us to fully understand the villain in action. One Piece plays with this trope so well that with each new arc, one of the most eagerly anticipated events is the reveal of the bad guy's backstory. To the point that when we don't get this, it can leave us feeling upset and disappointed. There's a feeling of insufficiency, a shortfall, a deficit. Take Kaido for example, perhaps the greatest example of a villain who has become very polarizing, exactly for this reason of a lack of a fully fleshed out backstory. Kaido was one of, if not the most highly anticipated villains, and was the major antagonist of the most highly built up arc in the series to date. And it is true that we did receive glimpses of his backstory through very short snippets of flashbacks, but I know I'm not alone when I say that I still wish we get a greater extension of his story somewhere down the line. Something that could be easily achieved by delving into his history during the inevitable rocks flashback. Now whether we will actually get that extension of Kaido's story is uncertain, but there is one villain who feels like an absolute home run when it comes to receiving such a lengthy backstory, and that is Marshall D. Teach, aka Blackbeard. Expected by many to be Luffy's final opponent, Blackbeard's been linked to some of the most important events and characters in the series. This man is indirectly or directly responsible for huge events that have changed the entire course of One Piece, such as the deaths of Ace and Whitebeard, and it's perhaps even the driving force for the majority of Shanks' actions. Not to mention his highly suggested connections to Rocks Deezerbeck. If One Piece is a puzzle to be completed, then the story of Blackbeard is a crucial piece. And I have to say that even without a complete backstory, Blackbeard's already a very interesting villain. He's a very calculating individual, which is a great quality that makes for a good villain, but his allure as a character goes even deeper than that. Maybe it's due to his inconsistent nature, because he does intriguingly have some very contradicting qualities. The ultimate opportunist, it's hard to believe that his perfectly executed plans are only in part conjured and in part him just getting really lucky. He's shown courage in some occasions, such as in his confidence to execute his plan, despite being within close proximity to some of the most dangerous Pirates of the Seas. And then on other occasions, we see him coward during confrontations, only to quickly switch back to high levels of confidence and cockiness again. Achieving his goals involves him running over people, making enemies, and losing friends in the process. But he himself doesn't seem to actively express any resentment, and there's also how he's achieved all that he has under that initial perfect disguise as a pirate with low ambitions. Keeping him out of everyone's radar. He was everywhere, but nowhere. And now, most interestingly, finally seeing Shanks makes me realize we are really getting closer to finding out Blackbeard's true nature, or rather, what sort of history has led him to being the way that he is now. Similar to as Shanks has just done, Blackbeard is about to make another very impactful appearance, and very very soon. A feeling that only gets stronger with each time Shanks makes the effort of keeping tabs on Blackbeard's movements, promising a very tantalizing relationship between the two. After all, Shanks and Blackbeard's story has always been intertwined, and it goes beyond the battle we know that they had in the past, that left Shanks with the three scars across his face, and perhaps the reason for Blackbeard's missing teeth. In many other aspects, these two share a rich history, and even have some interesting similarities. I mean, there's their shared love for drinking and partying for one, but also, both men were once apprentices to perhaps two of the most legendary pirates who ever lived. Shanks with Roger, the late pirate king, and Blackbeard with the world's strongest man, Whitebeard, who was arguably Roger's greatest rival. Even both their introductions have similarities, with each of them having an argument with the series' protagonist, Luffy, in a bar. Shanks about Luffy becoming a pirate, and Blackbeard about their polar opposite taste buds. And if the idea of Shanks being the son of Zabeck turns out to be true, then that's another connection to draw them closer. It could be one of those strange twists of fate where Blackbeard is carrying the wheel of Shanks' biological father. I mean, of course, there are also differences. Perhaps the most obvious one can be seen in how they battle. Shanks heavily relies on the use of haki, and the red-haired pirates are established to be non-devil fruit-holding haki experts, while Blackbeard uses the power of multiple devil fruits, and the Blackbeard pirates are somewhat devil fruit collectors. And this even goes back to their early days as apprentices with their respective crews, because Whitebeard was the holder of the fruit set to be able to destroy the world, and the Whitebeard pirates were known to be devil fruit users, even having a custom of whoever finding the devil fruit, getting to keep it for himself. The Roger pirates, on the other hand, had no known devil fruit users outside of Buggie, and even then they were skeptical about his fruit as we saw in the flashback. So just that idea alone of how these two have been built up in parallel to each other makes a lot of people extremely excited for this face-off. And now that one piece has stepped on the gas pedal, with each new chapter feeling like it's leading to bigger and bigger events, the story of Shanks and Blackbeard is poised to be one of the greatest highlights of the series. Which got me thinking, what will this face-off lead to? Because as of right now, Shanks' portrayal is that of an unbeatable force, but Blackbeard is expected to be Luffy's final opponent, so him losing to Shanks in their inevitable confrontation doesn't seem to serve a great purpose in the story. Which has me wondering, will Shanks be written out of the story somehow to make room for Luffy to do the hero's job of saving the world from Blackbeard's darkness? And now in order for me to talk about this next part, I have to preface there are going to be some spoilers for my hero academia, Injujutsu Kaisen, so if you aren't far into this series, then you should skip to the time shown on the screen. One of the most popular and effective tropes in anime right now is to have an insurmountable strong character that is on the good guy side. Whenever hope is lost and our heroes are faced with what seems to be an impossibly strong enemy, the strong good guy appears to deal with it. And the most popular examples of this are One Punch Man, Saitama, My Hero Academia is all mine, Injujutsu Kaisen, Satoru Gojo. But to make for an interesting story by increasing the tension, these strong characters are somehow written out of the plot. Examples being All Might Loosing His Power and Gojo being sealed in the prison realm. Now these developments are obviously written to increase the stakes and to make for interesting hard fought battles because without doing so, these almighty characters can just simply show up and always win the battle for the good guy, not allowing for the development of the protagonist. And one piece may be faced with a similar situation with Shanks, now that he's been shown to be overwhelmingly powerful and being one of the good guys. And in my opinion, speaking from a surface level, there are two very obvious ways a story like this can go. One is to reveal Shanks as a bad guy, which has been a highly speculated idea for a while now and it wouldn't be very difficult for Oda to execute if this was the route he decided to go. I mean the entire story could be premised on the idea that ever since Luffy ate the Nika Devil Fruit, Shanks gave Luffy the goal of returning his straw hat once Luffy becomes a great pirate, knowing that this goes hand in hand with Luffy mastering the Devil Fruit and finding Shanks for the sole purpose of Shanks using Luffy for whatever evil deeds he's planning to accomplish. I mean that's just the short example of an idea, but you get the point. And this evil Shanks theory is an idea I've somewhat entertained in the past, but I've never really brought into it and especially now as we see more of him in action. So let's discuss the other method of writing Shanks out of the story, and that is to have him lose and possibly even die at the hands of Blackbeard. And doing this at this point in the series would achieve a couple of things. It would give greater reasons and motivation for Luffy to be the one to defeat Blackbeard and it would also increase the level of tension in the story by way of a tragedy. This way, even if we know that Luffy will eventually defeat Blackbeard, seeing Blackbeard defeat someone as powerful as Shanks would give him an impressive achievement to add to his resume before he inevitably faces off against Luffy, thereby raising the stakes in tension and therefore our investment and attention. I mean after all, we've followed Luffy's story for over two decades now and we've witnessed him collecting win after win, arc after arc, and I think the quickest way to fast track increasing the level of Blackbeard's threat to the point that it feels like Luffy is truly in danger is by having him kill Luffy's hero. And at this point, I do also want to mention that I think Shanks dying, as opposed to just losing, is an important distinction to make. Because Shanks merely losing to Blackbeard opens the window for an argument that Shanks could simply recover and battle Blackbeard another time, and it also wouldn't achieve the same level of drama and motivation for Luffy. And the alternative would be for Blackbeard to fight Luffy after having just defeated Shanks, but not definitively so. And saying that already makes me feel like it tarnishes Luffy's character. I mean imagine getting cheated out of seeing a proper battle between Luffy and Blackbeard, because Luffy just simply defeats a tired, injured Blackbeard. After all, I don't see Shanks going down without a fight. I think whatever the result of the battle between Shanks and Blackbeard will end up with both men near death. Because apart from Shanks being one of Oda's favorite characters, he wasn't built up to the extent that he had just to lose without putting up much of a fight. Shanks will also obviously get the chance to showcase the full extent of his abilities, and this is something I'm confident to say we won't get robbed of. So for Luffy to just swoop in and land the final blow to an already weakened Blackbeard, during a state when he's just fought and not achieved a definitive win against Shanks, it just doesn't sound right. Because when the going gets tough and Luffy starts struggling against whatever powers Blackbeard has at that stage, there would always be that chance that maybe Shanks will have recovered to come in and help. Whereas the way that I imagine it, it has to be a fight between just Luffy and Blackbeard. A fight between two men, two sides of the same coin, fighting it out, not on just the matter of pride or strength, but also to prove their ideals. Now I hope this video isn't getting too depressing for you. And I guess Shanks doesn't necessarily have to die, so you know what, if you've made it this far into the video, why don't you comment on some other ways that Shanks can be written out of the story so that Luffy will be the one to defeat Blackbeard. For example, another idea is to have Blackbeard hold Shanks's life by a thread and in another twist of fate, Luffy will then have to save his hero. And this would give Luffy a chance to return the favor to Shanks in saving his life, which is one of the most iconic moments in the series. But it also completely reverses Shanks as a character. And you could argue that that could be a good thing, but I'd personally say that a warrior's end seems more fitting for Shanks. Blackbeard defeating Shanks using underhanded tactics is almost to be expected. And that way, Shanks's reputation doesn't get completely tarnished by his loss, or maybe you could even have another situation where Shanks saves Luffy again and this time around loses more than just his arm. I don't know, I'm just rambling at this point. But I have also arrived at that same idea again about Shanks dying, so I may as well commit to it at this point. So imagine this, a situation where Shanks is defeated and killed by Blackbeard, resulting in the ultimate battle between Luffy and Blackbeard. Luffy is now determined to fight and defeat Blackbeard, and not just to avenge his mentor, but because it also allows him to prove himself. We know that Luffy's been trying to fulfill his promise or oath to become a great pirate, one even greater than Shanks, but now with Shanks gone, the only way he can prove this is by defeating Blackbeard. Luffy facing Blackbeard, the man who beat Shanks, will be the ultimate test, and Luffy defeating Blackbeard will demonstrate that he's surpassed Shanks, achieving what he set out to do from the very beginning. And now I know I've gone on a little bit of a tangent here, but this is a topic I've been thinking about more and more lately. And it does relate to my point at the very beginning. A hero is only as good as its villain, and Luffy is our protagonist, our indomitable main character, who's going to surpass the glory and light that's shown on all the legendary figures before him. So then, if Blackbeard is our main antagonist, it just follows that he's going to have to be more depraved and darker than any other villain we've witnessed before him. And it seems like one of the darkest characters that Oda has set up in One Piece is Roxy Zabe. So it's fitting that he's already hinted at some sort of connection between these two figures. Maybe it'll even parallel the relationship between Luffy and Shanks.  It's not the mere fact that this will enrage Luffy. Because Oda has portrayed Shanks in such a cool light for such a long time for a reason. There's a reason why Shanks has been lurking in the shadows only to steal the spotlight each time he makes an appearance. Because the moment that Blackbeard extinguishes Shanks' light for good, there's gonna be no question as to how we view Blackbeard. And there's gonna be no greater satisfaction than when we see Luffy trump Blackbeard and restore the light. So anyways, these are just some things that have been running through my head. Developments that were built up decades prior finally seem to be starting to take place. And it seems that these seeds that were planted long ago are ripening into very delicious fruits. So as usual, thank you for listening to another one of my rambling thoughts. This is Joygirl and I'll see you again soon.