Masonite Framework 2.0 Patch

Joseph Mancuso - Jun 25 '18 - - Dev Community

The Patch and Challenge

Masonite is a pretty young framework and has a pretty young community. While building an awesome dashboard package for Masonite, I realized that a package I was working on was not working the same as it was with Masonite 1.6. More specifically, I was able to add static files to Whitenoise via a Service Provider but not I was not able to in 2.0.

Those familiar with Laravel and Service Providers, I present you a challenge. This challenge is to find what is wrong with this code snippet below.

The answer is below it so don't peak!

for provider in container.make('ProvidersConfig').PROVIDERS:
    located_provider = provider()
    located_provider.load_app(container).register()
    if located_provider.wsgi:
        container.make('WSGIProviders').append(located_provider)
    else:
        container.resolve(located_provider.boot)
        container.make('Providers').append(located_provider)

Not sure what it is? I can give you a hint.

for provider in container.make('ProvidersConfig').PROVIDERS:
    located_provider = provider()
    located_provider.load_app(container).register() # <-- this line
    if located_provider.wsgi:
        container.make('WSGIProviders').append(located_provider)
    else:
        container.resolve(located_provider.boot) # <-- and this line
        container.make('Providers').append(located_provider)

Find it yet? Ok I'll just tell you. This problem is that not all Service Providers have registered before all Service Providers have booted.

The Patch

The fix is to restructure the code to be like this:

for provider in container.make('ProvidersConfig').PROVIDERS:
    located_provider = provider()
    located_provider.load_app(container).register()
    if located_provider.wsgi:
        container.make('WSGIProviders').append(located_provider)
    else:
        container.make('Providers').append(located_provider)

for provider in container.make('Providers'):
    container.resolve(provider.boot)

You can patch this in your Masonite 2.0 applications.

My Thoughts and Possible Solutions

So the framework is young and we will have mistakes like this from time to time until the framework becomes extremely stable. There were a few solutions to this problem.

Solution 1 - New Major Release

This would entail everybody upgrading the framework from 2.0 to 2.1. It would require updating the documentation to 2.1 (without any documentation changes) and would mean a lot of confusion for people who didn't get the message

So this solution wasn't really a possibility.

Solution 2 - Patch All New Applications

We could simply make the fix in all future applications of Masonite but the problem will now arise that now there are technically 2 different versions of Masonite 2.0. 1 version with the patch and 1 without. This will make packaging hard.

The Winner

The solution we are going to be choosing for this problem is that we will release the next minor version of Masonite. In this new 2.0.x version will be a new function that looks like this:

def _check_patch(self):
    patched = False

    with open('wsgi.py', 'r') as file:
        # read a list of lines into data
        data = file.readlines()

    # change the line that starts with KEY=
    for line_number, line in enumerate(data):
        if line.startswith("for provider in container.make('Providers'):"):
            patched = True
            break

    if not patched:
        print('\033[93mWARNING: {}\033[0m'.format('Your Application Is Not Patched!'))

And we can put it inside the serve command:

def handle(self):
    self._check_patch() # <-- New Line Here

    if self.option('reload'):
        self._run_with_reloader(extra_files=[".env"])

    else:
        self._run_application()

What this will do is scan your wsgi.py file for the patch and if it does not detect it then it will show the error when you run craft serve.

Once you make the changes, Masonite will no longer show the warning message.


Again, the framework is young (but mature) and there may be some mistakes like this in the code. Very few parts of the framework are in the application itself so most fixes are made by upgrading Masonite itself. There are small parts of the framework that are inside the applications that are created and there is a small margin of error that can happen.

We'll need to work together as a community to find these issues and make Masonite a better framework we can all enjoy :)

. . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player