mylanconnolly
mylanconnolly
Explore posts from servers
FFilament
Created by mylanconnolly on 7/24/2024 in #❓┊help
Encountering poor performance in production after a number of troubleshooting steps
Hello all, I nearly have an MVP set up for my application but I think the performance of it is going to be an issue. Each page in the application takes roughly 1.5 seconds to load, with the vast majority of that time being server response time (roundtrips to and from the server and SSL negotiation are around 100ms). I have configured Clockwork on my server and when I have it enabled to see where the bottlenecks lay, it shows roughly 100ms in database queries and the rest as "controller". If I try to enable xdebug to try and get more details it doesn't work so I have skipped that for now. A few notes on my setup: - My app is hosted using php-fpm (version 8.3.9). My web server is Caddy. - My database is on another server in the same region, but database time seems to be relatively low. - I have enabled opcache, and it seems to be working. - When deploying the app, the following commands are run in order:
php artisan optimize
php artisan icons:cache
php artisan filament:cache-components
sudo /usr/bin/systemctl restart horizon
sudo /usr/bin/systemctl restart php8.3-fpm
php artisan optimize
php artisan icons:cache
php artisan filament:cache-components
sudo /usr/bin/systemctl restart horizon
sudo /usr/bin/systemctl restart php8.3-fpm
I saw that a lot of permission checks are performed so I tried to make those faster. I think it's important to note that this is not on pages that have a ton of records on them. Generally, I'm testing on pages with an empty table. I'm relatively new to PHP and since Filament is such a large codebase I'm trying to find my way around to determine how best to improve the performance but I'm a bit stuck. Any pointers would be greatly appreciated!
8 replies
FFilament
Created by mylanconnolly on 3/7/2024 in #❓┊help
Can we modify the dd tag that contains custom infolist entries?
Hello all, I was working on creating a custom infolist entry for my app (basically a scrollable pre tag for fixed-width text. After playing around with my component for a while I determined I can't get it to work correctly without modifying the dd tag that encloses my custom list entry component. Is there a way to do this? I see the emitted HTML has an empty class attribute but I couldn't figure out how to modify that in the docs. I'd appreciate any assistance. Thanks!
4 replies
AEAsh Elixir
Created by mylanconnolly on 8/15/2023 in #support
Ash JSON API is showing an error when following tutorial
Hello, after taking a break from Phoenix and Ash, I decided to move forward with my side project. When setting up the ash_json_api extension, I got the following error:
Compiling 18 files (.ex)
error: function plug/2 imported from both Phoenix.Router and Plug.Builder, call is ambiguous
lib/platform_web/router.ex:10: PlatformWeb.Router (module)


== Compilation error in file lib/platform_web/router.ex ==
** (CompileError) lib/platform_web/router.ex: cannot compile module PlatformWeb.Router (errors have been logged)
(phoenix 1.7.7) expanding macro: Phoenix.Router.pipeline/2
lib/platform_web/router.ex:9: PlatformWeb.Router (module)
Compiling 18 files (.ex)
error: function plug/2 imported from both Phoenix.Router and Plug.Builder, call is ambiguous
lib/platform_web/router.ex:10: PlatformWeb.Router (module)


== Compilation error in file lib/platform_web/router.ex ==
** (CompileError) lib/platform_web/router.ex: cannot compile module PlatformWeb.Router (errors have been logged)
(phoenix 1.7.7) expanding macro: Phoenix.Router.pipeline/2
lib/platform_web/router.ex:9: PlatformWeb.Router (module)
I added it to my Phoenix router like so:
use AshJsonApi.Api.Router,
apis: [Platform.Clinical],
json_schema: "/json_schema",
open_api: "/open_api"
use AshJsonApi.Api.Router,
apis: [Platform.Clinical],
json_schema: "/json_schema",
open_api: "/open_api"
I am using Phoenix 1.7.7 and Elixir 1.15.4. Is this a known thing or did Phoenix maybe change some internals? Thanks!
4 replies
AEAsh Elixir
Created by mylanconnolly on 4/16/2023 in #support
Issue using datetime_add
Hello, thanks again for the awesome library, I was trying to get into some more useful functionalities of Ash (calculations, etc.) and I'm mostly having a good time learning about it but there was one bit that I was having a hard time with. I was modeling an appointment, which I wanted to store the start date and the duration of. I thought calculating the end time would be useful, so I added made the following resource:
use Ash.Resource, data_layer: AshPostgres.DataLayer

# ...

calculations do
calculate(
:end_time,
:utc_datetime,
expr(datetime_add(start_time, duration, :minute))
)
end

attributes do
uuid_primary_key(:id)

attribute :start_time, :utc_datetime do
allow_nil?(false)
end

attribute :duration, :integer do
default(30)
end

attribute(:description, :string)

timestamps()
end
use Ash.Resource, data_layer: AshPostgres.DataLayer

# ...

calculations do
calculate(
:end_time,
:utc_datetime,
expr(datetime_add(start_time, duration, :minute))
)
end

attributes do
uuid_primary_key(:id)

attribute :start_time, :utc_datetime do
allow_nil?(false)
end

attribute :duration, :integer do
default(30)
end

attribute(:description, :string)

timestamps()
end
If I attempt to load the calculation, I get an error:
Mindset.Patients.Appointment.read_all(load: :end_time)
** (Postgrex.Error) ERROR 42846 (cannot_coerce) cannot cast type interval to timestamp without time zone
Mindset.Patients.Appointment.read_all(load: :end_time)
** (Postgrex.Error) ERROR 42846 (cannot_coerce) cannot cast type interval to timestamp without time zone
This is the SQL that is generated:
SELECT a0."id", a0."start_time", a0."duration", a0."description", a0."inserted_at", a0."updated_at", a0."patient_id", a0."start_time"::timestamp + (a0."duration"::bigint::numeric * interval '1 minute')::timestamp FROM "client_0d98e96c-ddb3-43e2-98ee-df027173c950"."appointments" AS a0
SELECT a0."id", a0."start_time", a0."duration", a0."description", a0."inserted_at", a0."updated_at", a0."patient_id", a0."start_time"::timestamp + (a0."duration"::bigint::numeric * interval '1 minute')::timestamp FROM "client_0d98e96c-ddb3-43e2-98ee-df027173c950"."appointments" AS a0
If I tweak it to include parentheses around the timestamp calculation, it works:
SELECT a0."id", a0."start_time", a0."duration", a0."description", a0."inserted_at", a0."updated_at", a0."patient_id", a0.("start_time"::timestamp + (a0."duration"::bigint::numeric * interval '1 minute'))::timestamp FROM "client_0d98e96c-ddb3-43e2-98ee-df027173c950"."appointments" AS a0
SELECT a0."id", a0."start_time", a0."duration", a0."description", a0."inserted_at", a0."updated_at", a0."patient_id", a0.("start_time"::timestamp + (a0."duration"::bigint::numeric * interval '1 minute'))::timestamp FROM "client_0d98e96c-ddb3-43e2-98ee-df027173c950"."appointments" AS a0
Is there something I'm doing incorrectly in defining the calculation? Thanks!
6 replies
AEAsh Elixir
Created by mylanconnolly on 3/15/2023 in #support
Using manage_relationship with nested relationships
I have three resource modules:
defmodule Patient do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "patients"
repo Repo
end

attributes do
uuid_primary_key(:id)
attribute(:first_name, :string)
attribute(:last_name, :string)
timestamps()
end

relationships do
has_many :event_series, EventSeries
end
end

defmodule EventSeries do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "event_series"
repo Repo

custom_indexes do
index [:patient_id, :initial_date], unique: true
end
end

attributes do
uuid_primary_key(:id)
attribute(:initial_date, :date)
timestamps()
end

relationships do
belongs_to :patient, Patient, allow_nil?: false
has_many :exams, Exam
end
end

defmodule Exam do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "exams"
repo Repo
end

attributes do
uuid_primary_key(:id)
attribute(:performed_on, :date)
timestamps()
end

relationships do
belongs_to :event_series, EventSeries, allow_nil?: false
end
end
defmodule Patient do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "patients"
repo Repo
end

attributes do
uuid_primary_key(:id)
attribute(:first_name, :string)
attribute(:last_name, :string)
timestamps()
end

relationships do
has_many :event_series, EventSeries
end
end

defmodule EventSeries do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "event_series"
repo Repo

custom_indexes do
index [:patient_id, :initial_date], unique: true
end
end

attributes do
uuid_primary_key(:id)
attribute(:initial_date, :date)
timestamps()
end

relationships do
belongs_to :patient, Patient, allow_nil?: false
has_many :exams, Exam
end
end

defmodule Exam do
use Ash.Resource, data_layer: AshPostgres.DataLayer

postgres do
table "exams"
repo Repo
end

attributes do
uuid_primary_key(:id)
attribute(:performed_on, :date)
timestamps()
end

relationships do
belongs_to :event_series, EventSeries, allow_nil?: false
end
end
With this in place, I was able to figure out how to insert patients into the database pretty easily, however my problems arose when trying to do the exams. The exams are loaded from an outside data source where we derive the event series based on a date value. So what I tried to do was:
Exam
|> Ash.Changeset.for_create(:create, %{performed_on: performed_on})
|> Ash.Changeset.manage_relationship(:event_series, %{patient_id: patient_id, initial_date: examdate}, type: :append_and_remove, on_no_match: :create)
|> Api.create()
Exam
|> Ash.Changeset.for_create(:create, %{performed_on: performed_on})
|> Ash.Changeset.manage_relationship(:event_series, %{patient_id: patient_id, initial_date: examdate}, type: :append_and_remove, on_no_match: :create)
|> Api.create()
When doing this, an error is returned saying that the event series is invalid because the patient relationship is not defined. Is it possible to do this with a call to manage_relationship or am I fundamentally missing something? Thanks so much for any assistance, Ash is very cool so far!
22 replies