booni3

booni3

Member Since 1 Year Ago

Experience Points
9,310
Total
Experience

690 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
51
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 2
9,310 XP
Mar
11
4 weeks ago
Activity icon

Started a new Conversation [7.x] Blade Components - "Undefined Variable" (fails On Vapor Only)

I have a simple button component that I am trying to provide some colour logic with a fallback when none is provided.

  • My local machine is running php 7.4.3.
  • Vapor is on 7.4.1 I believe
  • Laravel 7.1.0
<button type="button" 
{{ $attributes->merge(['class' => "inline-flex ".($colour)] }}>
  {{ $slot }}
</button>
class button extends Component
{
    public $colour;

    public function __construct($colour = null)
    {
        if (! $colour) {
            $this->colour = 'blue';
        } else {
            $this->colour = $colour;
        }
    }
...

When passing no variable as below, we get an "Undefined variable" exception, on Vapor only.

<x-button>Save</x-button>

If we then pass in the colour attribute:

<x-button colour='blue'>Save</x-button>

We get the below html on Vapor (note the colour attribute being outputted as HTML)

<button type="button" class="inline-flex" colour="blue">
  Save
</button>

vs. this on local/valet:

<button type="button" class="inline-flex blue">
  Save
</button>

So local works as I would expect, but vapor fails with:

  1. "Undefined variable" exception thrown if we do not pass a variable, even though we are defaulting to a fallback in the class.
  2. When passing in the variable, it does not merge into the attributes.
Feb
29
1 month ago
Activity icon

Awarded Best Reply on Attaching A Belongs To Model After Creation

This is actually what I was looking for. It does them same thing under the hood I am sure but communicates much better.

$channel = Channel::firstOrCreate(['name' => $name]);
$channel_mapping->channel()->associate($channel)->save();
Activity icon

Replied to Attaching A Belongs To Model After Creation

This is actually what I was looking for. It does them same thing under the hood I am sure but communicates much better.

$channel = Channel::firstOrCreate(['name' => $name]);
$channel_mapping->channel()->associate($channel)->save();
Activity icon

Replied to Attaching A Belongs To Model After Creation

Thanks. That does not work in this case though.

  • A ChannelMapping BelongsTo a Channel
  • A Channel HasMany ChannelMappings

The channel mapping has already been created, without a related channel channel_id = null

So, the flow is:

  1. Channel Mapping is made without a channel
  2. Channel Mapping is linked to a channel

The proposed solution:

$channel_mapping->channel()->create(['name' => $name]);

will make a new channel but will not link it to the channel mapping as the foreign key is on the channels_mappings table.

Creating the channel and then updating the channel mapping is 2 queriers but I wonder if the best way to do it.

Activity icon

Started a new Conversation Attaching A Belongs To Model After Creation

I have a channel mapping model with;

public function channel(): BelongsTo
{
    return $this->belongsTo(Channel::class);
}

After I have created a channel, I need to link it to the channel mapping. With belongsToMany we can do attach, but with just belongsTo do we have a better option than this?

$channel = Channel::firstOrCreate(['name' => $name]);
$channel_mapping->update(['channel_id' => $channel->id]);

I was thinking something like this should exist?

$channel = Channel::firstOrCreate(['name' => $name.'/'.$identifier]);
$channel_mapping->attach($channel);
Feb
23
1 month ago
Activity icon

Replied to InsertOrIgnore & Json Encode With Array Casting On Model

I am using insert ignore for performance. We are inserting up to a few million rows per 24 hours and first or new runs 2 queries instead of 1. I would generally never use insert ignore but it seems much better in this scenario apart from my issue with the json encoding.

Activity icon

Started a new Conversation InsertOrIgnore & Json Encode With Array Casting On Model

My model is setup with an array cast;

protected $casts = [
    'document' => 'array'
];

So if I use the create method, my array is converted to json and escaped on the way into the database.

With insertOrIgnore we bypass this function and I have to manually json_encode the array;

self::insertOrIgnore([[
    'document' => $document ? json_encode($document) : null,
]]);

However, doing this does not escape the json string as it would do with Laravel. How can I manually escape the string for use with insertOrIgnore? The below does perform an escape, but not the correct one.

DB::connection()->getPdo()->quote(json_encode($document))
Feb
22
1 month ago
Activity icon

Replied to Factory Stub For Large JSON Body

I went for this in the end, seems to work quite well and is fairly concise;

factory(OrderDocument::class, 10)->make()->each(function(OrderDocument $model, $i){
    $stub = base_path("tests/stubs/stub_$i.json");
    $model->document_id = File::name($stub);
    $model->document = File::get($stub);
    return $model->save();
});
Feb
20
1 month ago
Activity icon

Replied to Factory Stub For Large JSON Body

Is there a way I can use this within a factory? otherwise I think this is quite similar to the way I am currently using it, just without the file_get_contents;

foreach ($this->fullDocuments() as $id => $document){
    $a = factory(\App\OrderDocument::class)->create([
        'document_id' => $id,
        'status' => 'full',
        'synced_at' => null
    ]);
    $a->setRawAttributes(['document' => $document]);
    $a->save();
}

Ideally I want to be able to say, "give me 1 record" or "give me 10 records".

Is it possible to iterate within a factory? i.e. $i++ below

factory(OrderDocument::class, 10)->create([
    'document_id' => $this->getDocumentId($i++),
    'document' => $this->getDocumentStub($i++),
]);
Activity icon

Started a new Conversation Factory Stub For Large JSON Body

I am pulling order information from an external API and saving the entire JSON response into a documents table.

I obviously do not want to call this API when testing so I have setup a factory, but I am struggling with how to pull in these JSON stubs. For example:

// factory

$factory->define(App\OrderDocument::class, function (Faker $faker) {
    return [
        'document_id' => $faker->uuid,
        'status' => $faker->randomElement(['open', 'partial', 'processed', 'updating']),
        'document' => $faker->text
    ];
});

// Currently using it like...

foreach ($this->fullDocuments() as $id => $document){
    $a = factory(\App\OrderDocument::class)->create([
        'document_id' => $id,
        'status' => 'full',
        'synced_at' => null
    ]);
    $a->setRawAttributes(['document' => $document]);
    $a->save();
}

where $this->fullDocuments() contains an array of the document_id and raw JSON response from the API.

I know a better way to do this is to factory the entire JSON document. The JSON contains about 500 lines so it would be very time consuming but also I do not own this data, so I assume I should not be trying to fake it.

Within my test, I would prefer to do something like the below, but am not sure how.

factory(OrderDocument::class, 10)->create([
    'document_id' => $this->getDocumentId($i++),
    'document' => $this->getDocumentStub($i++),
]);
Feb
19
1 month ago
Activity icon

Started a new Conversation Guzzle HTTP Package - How Should I Handle Exceptions For My Open Source Package?

I am creating a package to connect to a 3rd party API, using guzzle. I intend to publish this as an open source package. I am wondering what the general convention is in terms of providing an error response to the user. I have 2 main options in mind.

  1. Throw an exception (straight from Guzzle or catch and throw my own)
try {
    $response = $this->client->get($this->server.$endpoint, [
        'form_params' => $parameters,
        'headers' => [
            'Content-Type' => 'application/x-www-form-urlencoded',
            'Authorization' => $this->bearer
        ]
    ]);

    return json_decode((string) $response->getBody(), true);

} catch (ClientException $e) {
    /**
     * Do some work here to process any known exceptions
     */

    throw $e;
}
  1. Catch all exceptions and convert them to an array. i.e. return the exception message for the user to process as they would like.
try {
    $response = $this->client->get($this->server.$endpoint, [
        'form_params' => $parameters,
        'headers' => [
            'Content-Type' => 'application/x-www-form-urlencoded',
            'Authorization' => $this->bearer
        ]
    ]);

    return json_decode((string) $response->getBody(), true);

} catch (ClientException $e) {
    throw new \Exception((string) $e->getResponse()->getBody(), $e->getResponse()->getStatusCode());
}
Feb
13
1 month ago
Activity icon

Started a new Conversation Extending/Replacing A Core Trait

Is this possible? I am using a multi-tenancy package that conflicts with other Laravel packages such as Scout. Ideally I want to be able to replace/extend the Illuminate\Queue\SerializesModels trait within the core.

Obviously the other way to do this is just replace that trait with my own one in every job that runs, but it does then mean in the case of things like Laravel Scout I have to rewrite the scout classes, just to replace this one trait, within my own app which feels wrong.

Is this possible? I am using a multi-tenancy package that conflicts with other Laravel packages such as Scout. Ideally I want to be able to replace/extend the Illuminate\Queue\SerializesModels trait within the core.

Obviously the other way to do this is just replace that trait with my own one in every job that runs, but it does then mean in the case of things like Laravel Scout I have to rewrite the scout classes, just to replace this one trait, within my own app which feels wrong.

As an example, Laravel Scout has the MakeSearchable job class. In order to replace the trait in this model I have to make my own implementation of the class which is identical to the package apart from changing this one trait:

class MyMakeSearchable implements ShouldQueue
{
    use TenantAware, Queueable, MySerializesModels;

    /** @var Collection */
    public $models;

    public function __construct($models)
    {
        $this->models = $models;
    }

    public function handle()
    {
        if (count($this->models) === 0) {
            return;
        }

        $this->models->first()->searchableUsing()->update($this->models);
    }
}

To connect up this job class, I then have to override the Scout Searchable trait too.

It would be nice if I could just say to Laravel "Whenever you want this SerializesModels trait, use this one instead`

Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

I opened an issue with Laravel but it was closed... its more a MySQL thing. They did not seem too interested in it as an issue or feature.

Activity icon

Replied to Vapor Timeout Not Being Ignored

Thanks. I assume attempts is taken into account also? The exception message is a little confusing as even on the final attempt I think it still says this?

Feb
12
1 month ago
Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

Done, thanks for your help

Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

I should have done

Model::whereIn('uuid', $uuids)

but actually did

Model::whereIn('uuid', $ids)
Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

My model;

// Model.php
protected $casts = [
    'uuid' => 'string'
];

The problem in this case, was I was passing in the wrong array into the whereIn. I was supposed to pluck a uuid from another model but accidentally plucked the id column. I just would like to have a bit more protection from this happening as out of a table with 12,000 rows we actually matched and updated 6000 of them even though the ID's did not match.

Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

I would effectively need to do something like:

Model::whereIn('uuid', array_map('strval', $this->ids))

Is there anything more elegant to this? If we know the UUID column is always going to be a string, can we somehow set a casting to the query array more globally? Kind of like in the model casting array but acting on the eloquent whereIn method.

Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

I tried casting the column type to string (in the model casts array) but that makes no difference to the result. It seems strange I would need to pre-process the whereIn array to ensure it is all forced to a string before the query is run.

Activity icon

Replied to WhereIn Is Returning Results Only With Partial Matches

Thanks for the quick reply. Yes a string works as expected.

Activity icon

Started a new Conversation WhereIn Is Returning Results Only With Partial Matches

For example:

Model::whereIn('uuid', [1])
    ->each(function(OrderDocument $orderDocument) {
        dd($orderDocument->uuid); // '1ab1fdeb-7e83-4be9-a1b4-52da267d2733'
    });

Passing an integer 1 into a whereIn against a UUID column, returns a match against 1ab1fdeb-7e83-4be9-a1b4-52da267d2733

The Laravel docs state:

whereIn / whereNotIn / orWhereIn / orWhereNotIn

The whereIn method verifies that a given column's value is contained within the given array:

$users = DB::table('users')
                    ->whereIn('id', [1, 2, 3])
                    ->get();

To me that does not suggest anything about a partial match.

If this is intentional, is there anything else I can do to make this more strict?

Feb
10
1 month ago
Activity icon

Replied to Vapor Timeout Not Being Ignored

@themsaid I see you have implemented at Laravel\Vapor\VaporJobTimedOutException exception - fast work 😄!

The {Job} has timed out. It will be retried again part; what does this mean exactly? Is this related to the retries parameter on the job? Will the timeout property set on the job also work now?

Feb
07
2 months ago
Activity icon

Replied to Laravel Scout Engine With Support Elasticsearch 7. Feedback Needed

Turns out I needed to publish the scout config too. Will report back when I have used it more :-)

Activity icon

Replied to Laravel Scout Engine With Support Elasticsearch 7. Feedback Needed

Hey,

I would really like to use this in a multi-tenant app with ElasticSearch7. However I am struggling at the moment to actually get any data imported into elastic-search other than the mappings.

I left a message on the repo incase there is a bug but I expect its setup issue...

Any help would be much appreciated.

Activity icon

Replied to Estimating IOPS

OK, so I see that a single query is not actually a single IOP.

The table I am inserting into has 7 columns excluding the create/update and it has 4 indexes. From what I have read, indexes have at least 1 IOP each and there will be a few other operational IOP's. Even If I said 10 IOP per transaction, that still only calculates to around 960 IOPS - much less than what the RDS monitoring is telling me.

Is there anything else I can check or optimise to try and reduce this. I really do not want to have to switch to a provisioned IOPS instance.

Activity icon

Started a new Conversation Estimating IOPS

I am having issues with my RDS instance maxing out its IOPS when we are competing long running report operations. I am currently only running a single script, 1 at a time and I am surprised that I am hitting 3000 IOPS over a prolonged period of time (hours) and getting bursts up to 7000 IOPS!

As far as I understand, an input/output operation to the RDS instance is a read or write query?

I have checked my script locally with the Laravel debug bar, and it contains 446 queries for the 1st run and then 204 queries for all subsequent runs.

I have it running in a queue with just a single worker (i.e. concurrency of 1) and checking on my logs and over the course of 10 minutes we can run 282 of these jobs.

By my calculations that is 408 + (204 x 281) = 57,732 queries in 10 minutes, 5,773 per minute or 96 per second.

What am I missing here to account for the 3000 - 7000 IOPS as registered by AWS monitoring?

Activity icon

Replied to Json Column Type Re-orders Data - How To Stop It? Is Text Ok Instead?

Thanks both - yes you can still cast to an array/object wither the field is text or json. It sounds like the key advantage of json columns is the fact they are searchable within queries, however with any large number of rows the performance is going to be significantly worse than an indexed varchar.

Feb
06
2 months ago
Activity icon

Started a new Conversation Json Column Type Re-orders Data - How To Stop It? Is Text Ok Instead?

I have noticed when saving arrays as json to a json type column, MySQL re-arranges the data in order to provide a more performant search of the data. For my application this is an issue, as I do not want to trigger update events if the json is actually the same as is in there already (regardless of the order it was saved).

So my questions are:]

  1. Is it possible to continue to use the json column type but force MySQL to not re-order the data in any way, so that when we do a json string comparison data that is the same is recognised as so.

  2. Is there any serious downsides to using the text type field if all we are doing is converting json into an array when needed. We are never searching against a json field or manipulating the data inside the column in any way.

Activity icon

Awarded Best Reply on Reusing Eloquent Builder Parameters Inside Query Builder Scope

Thank you! That was not quite it but it got me close.

This seems to work:

public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
    return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
        $queryBuilder->from(static::getTable())
            ->selectRaw("min(`$by`)")
            ->groupBy($fields ?? static::$groupedScopeFields);

            $queryBuilder->addNestedWhereQuery($query->getQuery());
    });
}
Activity icon

Replied to Reusing Eloquent Builder Parameters Inside Query Builder Scope

Thank you! That was not quite it but it got me close.

This seems to work:

public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
    return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
        $queryBuilder->from(static::getTable())
            ->selectRaw("min(`$by`)")
            ->groupBy($fields ?? static::$groupedScopeFields);

            $queryBuilder->addNestedWhereQuery($query->getQuery());
    });
}
Activity icon

Replied to Reusing Eloquent Builder Parameters Inside Query Builder Scope

Thats correct, in this case. Thanks for the fast reply :-)

Activity icon

Replied to Reusing Eloquent Builder Parameters Inside Query Builder Scope

This produces:

select * from `queue_jobs` where `started_at` is null and `id` in (select min(`id`) from `queue_jobs` group by `throttle_groups`) order by `id` asc

We are still just missing the

where started_at is null`

from

`id` in (select min(`id`) from `queue_jobs` group by `throttle_groups`...
Activity icon

Started a new Conversation Reusing Eloquent Builder Parameters Inside Query Builder Scope

I have a scope which picks out the first result per group for a set of results.

public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
    return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
        return $queryBuilder->from(static::getTable())
            ->selectRaw("min(`$by`)")
            ->groupBy($fields ?? static::$groupedScopeFields);
    });
}

This works, but it does not take into account any other conditions that were setup in the parent query. For example, the generated SQL output is:

select * from `queue_jobs` where `started_at` is null and `id` in (select min(`id`) from `queue_jobs` group by `throttle_groups`) order by `id` asc

But when the following whereNull is added to the parent query:

QueueJob::orderBy('id')
    ->whereNull('started_at')
    ->firstPerGroup(['throttle_groups'])
    ->get();

It should instead be:

select * from `queue_jobs` where `started_at` is null and `id` in (select min(`id`) from `queue_jobs` WHERE `started_at` IS NULL group by `throttle_groups`) order by `id` asc

Within the scope I need to somehow get the whereNull('started_at') (along with any other conditionals that may be added in. I somehow need to get these conditionals into the commented line below, but am unsure how.

public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
    return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
        return $queryBuilder->from(static::getTable())
            //->where... (I need to add in the the whereNull and whereType from parent query)
            ->selectRaw("min(`$by`)")
            ->groupBy($fields ?? static::$groupedScopeFields);
    });
}
Feb
04
2 months ago
Activity icon

Replied to Vapor Timeout Not Being Ignored

Can you clarify the situation with JobFailed event and failed job logging when the lambda timeout is hit? I accidentally left my timeout at 5 seconds yesterday queue-timeout: 5 and quite a few jobs run (and failed) overnight. Around 2000 jobs failed but only 10 have been captured in the failed_jobs table with Illuminate\Queue\MaxAttemptsExceededException.

If we timeout the Lambda function I am guessing that Larval shuts down and does not have time to record the failure... but then I still seem to get some. All my jobs are set to public $tries = 1 currently so this is not a failure due to retry attempts.

Feb
03
2 months ago
Activity icon

Started a new Conversation Vapor Timeout Not Being Ignored

I have a 60 second timeout set on my jobs and a 90 second vapor queue visibility timeout

abstract class AbstractJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, SerializesModels, InteractsWithQueue, Queueable;

    public $timeout = 60;

    public $tries = 1;

}

vapor.yml

queue-timeout: 90

I am still getting jobs that show up in cloudwatch as timing out after 90 seconds. Why is this?

REPORT  Duration: 90090.19 ms   Billed Duration: 90000 ms   Memory Size: 512 MB Max Memory Used: 213 MB  [+90091ms]

If I change my timeout to 5 seconds, then all my jobs seem to fail as expected.

Activity icon

Replied to Anyone Figured Out Logging Using Laravel Vapor?

Did this get paper working on vapor? I have tried the same but no luck

Activity icon

Started a new Conversation Testing JobProcessed Event Locally

I have some logic running within the jobProcessed event. This works fine in production with a redis queue but does not trigger locally with the sync driver enabled.

Are there any workarounds for this?

Jan
30
2 months ago
Activity icon

Replied to How To Rate Limit Jobs In Laravel Vapor. Job Bucket?

@bugsysha Can you just confirm your point on horizon? I tried to install it today and it does not seem compatible with Vapor even as a monitoring tool. Once installed we just get redis connection exceptions and a blank dashboard (our vapor does have a redis cache attached)

Activity icon

Replied to How To Rate Limit Jobs In Laravel Vapor. Job Bucket?

Thanks, but Horizon is just for monitering right? Unless they changed something recently.

My issue here is more to do with ensuring that we do not throw thousands of jobs into the queue that are going to get rejected and released many times. It just feels like a waste to do this to me...

What we have come up with for now, is a "job hopper" model/table, with a serialised instance of the job to be dispatched, which we dispatch to the queue with a throttle or concurrency check before actually dispatching. So this means we should in theory never have any jobs in the queue that our server or the API's do not have capacity for.

I know that Redis itself has the funnel and throttle methods but these require the job to be put into the queue and then released potentially hundreds or thousands of time until there is space... which does not feel very nice. I would love it if the throttle and funnel methods did not increase the attempts counter on the job.

Is that possible?

Jan
29
2 months ago
Activity icon

Replied to Dynamic Configuration In Service Provider

I am currently doing this in 2 ways. In both cases the configs are stored in a database.

  1. Within the service provider you use the user to lookup against the table and pull back the correct config. i.e. Auth::user->xero;

  2. You modify the flow of the script to push in the config before anything is run. I am doing this in most cases. i.e. in the constructor $xero = Xero::make($config)

Jan
27
2 months ago
Activity icon

Started a new Conversation How To Rate Limit Jobs In Laravel Vapor. Job Bucket?

Does anyone have any ideas on this...

  • I need a way to rate limit jobs run on vapor without using up invocations.
  • The rate limiting should be done on a key basis as with the usual redis style rate limiters.

The reason I do not think I can use a traditional approach is that they effectively work by starting the job and then checking if it can run. If it cannot then the job is released back into the queue. I want to be in a position where I can add 1000 jobs to a queue under a certain key and then allow (for example) 100 of them to be released and completed every minute.

I believe I could do this with a kind of job hopper. Fill a table up with serialized jobs, their key and rate etc. and then use a seeder job with a leaky bucket algorithm to dispatch jobs from my hopper.

What do you think? Any better ideas or a way this could be done within vapor natively?

Jan
05
3 months ago
Activity icon

Awarded Best Reply on Database Encryption At Rest - Amazon RDS Internal Vs. Application Level

From the research I have done, the primary need for at rest encryption is for either database server attacks or physical removal of the hardware storing data (i.e. theft of a hard drive).

When using Amazon RDS with a private network between your webserver and database server, both of the above scenarios are generally considered quite unlikely.

However, it is still a requirement by MWS that you have at rest encryption in place. In this case, there appears to be little difference between using Amazon RDS's in-built at rest encryption vs. encrypting/decrypting at application level.

The complexity of doing it at application level means in most cases RDS only encryption would be preferred.

Amazon MWS have confirmed that this is also the case as far as meeting their requirements.

Activity icon

Replied to Database Encryption At Rest - Amazon RDS Internal Vs. Application Level

From the research I have done, the primary need for at rest encryption is for either database server attacks or physical removal of the hardware storing data (i.e. theft of a hard drive).

When using Amazon RDS with a private network between your webserver and database server, both of the above scenarios are generally considered quite unlikely.

However, it is still a requirement by MWS that you have at rest encryption in place. In this case, there appears to be little difference between using Amazon RDS's in-built at rest encryption vs. encrypting/decrypting at application level.

The complexity of doing it at application level means in most cases RDS only encryption would be preferred.

Amazon MWS have confirmed that this is also the case as far as meeting their requirements.

Dec
31
3 months ago
Activity icon

Started a new Conversation Database Encryption At Rest - Amazon RDS Internal Vs. Application Level

We need to ensure our software is compliant with Amazon Marketplace Web Services (MWS) conditions of use. One key area is database encryption at rest for PII.

We use Amazon RDS and have encryption at rest enabled already (https://aws.amazon.com/rds/features/security/). On its own, this is our perfect solution as it allows simple data access and search from without our application.

Additional to the encryption provided by RDS, there are a lot of solutions available to repeat and/or replace this at an application level. i.e. a function is used to encrypt and decrypt the data into and out of the database. We have a simple encryptable trait on our models that used Crypt to encrypt and decrypt models into and out of the database. This is simple and works well for this one purpose but it prevents simple searching of records that is a key part of our application.

My question is... are both of these necessary? Amazon will be able to approve/disapprove our plan either way but I wonder more from a pragmatic viewpoint.

My thoughts are:

  • If the webserver is compromised then either way our data is likely to be exposed.

  • If the database server is compromised; whether we use RDS integrated encryption and/or our own then the data is secure.

Dec
25
3 months ago
Activity icon

Replied to Logging In Laravel Vapor (Papertrail, Flare, Sentry - Nothing Is Working!)

I went through a quite a few emails with papertrail and Taylor in regards to this. At least at a few months ago the answer was it is not compatible.

I would love to find a way to get paper trail to work!

Nov
24
4 months ago
Activity icon

Awarded Best Reply on Inject User Into Form Request - Testing Autorization

So I realise now that a unit test, may not be the best way to test this at all... but in answer to the original question:

'How to inject the user into form request, so that you can retrieve the user with $this->user()

$this->subject->setUserResolver(function () use($user) {
   return $user;
});
Activity icon

Replied to Inject User Into Form Request - Testing Autorization

So I realise now that a unit test, may not be the best way to test this at all... but in answer to the original question:

'How to inject the user into form request, so that you can retrieve the user with $this->user()

$this->subject->setUserResolver(function () use($user) {
   return $user;
});
Nov
23
4 months ago
Activity icon

Replied to Form Requests $this->user() Vs. Auth()->user() In Authorization

@nakov OK thank you. I guess in my head I was taking this unit test example and extrapolating it out to something more complex. For me, the main benefits I could see were a faster test and maybe not using so much of the request... but as you have suggested, maybe I am better off just sacrificing the speed and running all my options in a feature test.

So in your opinions for a form request like this, unit tests have no place?

Activity icon

Replied to Form Requests $this->user() Vs. Auth()->user() In Authorization

@tykus I am relitively new to testing so your advice is really appricated. I am following along with the confident laravel (https://confidentlaravel.com/) test training and it seems to suggest that it is OK to test the authorize method in a unit test, with a logged-in user.

You can see testing the unhappy path in this snippet (without user login):

https://recordit.co/d4doqQFyOy

and the happy one here (with user login):

https://recordit.co/eZuJTigv7a

Am I doing something different to what he is suggesting here, or do you just generally disagree with this method?

Activity icon

Replied to Form Requests $this->user() Vs. Auth()->user() In Authorization

thanks, @nakov . I agree I may not 100% understand the official constraints of unit testing. Maybe, in fact, I do want to be mocking a user for this test? Or maybe I just need to run every scenario I can think of through an integration test. My only concern with the integration test is that I am testing the whole flow through the request for every different scenario when all I really want to know is if the authorize passes or not.