travisf

travisf

I’m sending a daily report which should be showing the current time set to mountain daylight time. However, after daylight savings time the report has been consistently an hour behind. I if I run Timex.now("MDT") in the terminal I will get the current time in MDT. Our report is generated much the same way: {:ok, date} = Timex.format(Timex.now("MDT"), "{h12}:{m} {am}") Again, this works in my terminal but not on the report that gets sent out; it’s an hour behind.
However, if I change Timex.now("EST") I will get Eastern Time but an hour behind (right now it’s 11:15 EST but I’m getting 10:15).
Any ideas on what the cause of this might be? Is there a Phoenix config somewhere that sets time?

Showing Posts 23 to 14

thojanssens1

thojanssens1

I had that feeling :sweat_smile:

travisf

travisf OP

Ok this is very embarrassing… The original solution with the timezone did fix this issue. The continued issues we were seeing were due to a recent change in our deployments, we were just deploying an old release :man_facepalming:. We only deploy once a week or so otherwise I think we would have caught that sooner.

thojanssens1

thojanssens1

Sorry, I was asking how :at value is consumed, but you show the code that passes around the value, but not the code that really uses the value. :at is passed to start_missing_jobs!/2, but I still don’t know how the value is used.

More specifically (why I’m asking that), is I want to know what time zone is used, as you said your server is configured in UTC. So :at is 13pm (at: {13, 0, 0}) in what time zone?

and also code of do_format(date, @time_format)

travisf

travisf OP

Sorry @thojanssens1 I was handling some other things last week.

:at is consumed through a function in the orechestrator:

  defp to_entry_point_map(entry_point) do
    %{
      queue: Keyword.fetch!(entry_point, :queue),
      ...
      at: Keyword.get(entry_point, :at)
    }
  end

That function is called by the orchestrate function:

  def orchestrate(opts \\ []) do
    exq_pid = opts[:exq_pid] || ExqApi
    {:ok, scheduled_jobs} = ExqApi.scheduled(exq_pid)

    for entry_point <- entry_points() do
      entry_point
      |> to_entry_point_map()
      |> start_missing_jobs!(scheduled_jobs)
    end
  end

start_missing_jobs!/2 starts jobs that are scheduled based on the arguments consumed from to_entry_point_map/1

thojanssens1

thojanssens1

How is this :at option consumed?

travisf

travisf OP

Sure.
We have an ExqOrchestrator that is queueing jobs with Exq. The config file looks a little like this:

config :application, Application.Jobs.ExqOrchestrator,
 entry_points: [
    ...
 [
      queue: "report",
      worker: ReportWorker,
      task: "build_and_send_report",
      at: {13, 0, 0}
    ]
]

ReportWorker:

  def build_and_send_report(opts \\ []) do
   # enqueues job for tomorrow
      atrs = %{
        task: "build_and_send_report",
        args: %{},
        worker: @worker,
        queue: @queue
      }

      Jobs.perform_on(atrs, Timex.shift(Timex.now("America/Denver"), days: 1))

    # functions to actually send the report
    Reporting.send_report(opts)
  end

That’s Exq and the worker… Looking into the actual Reporting.send_report/1 the function starts to get a bit complicated because we are running a few database queries gathering information and then processing it but it eventually calls a deliver_email function which calls a ReportEmail module:

  def make_report(report_vals, opts \\ []) do
    new_email()
    |> from("email@example.com")
    |> put_recipients(opts)
    |> subject(dgettext("report",  "Daily Report "))
    |> put_layout({MailerView, :reporting})
    |> render(:daily_report, daily_report: report_vals)
  end

The layout in Mailerview contains the Timex.now() stamp that is shown on the email.

thojanssens1

thojanssens1

Can you show the code that shows how the report is sent at 13:00?

travisf

travisf OP

This report is sent by a worker which queues itself to run every 24 hours. There is a config file that starts several workers when the server is restarted with specific times each worker is to run. In the case of this report, 13:00 is the time the report gets sent, this works because we receive the report daily at 1.
The worker calls a function that actually builds the report. Inside that function, we assign an HTML template for the email.
The label in the email is this:

<%= dgettext("report", "Time: %{time}",
              time: format_date(Timex.now("America/Denver"), :time_only) 
       )
%>

format_date is

@time_format "{h12}:{m} {am}"
def format_date(date, :time_only), do: do_format(date, @time_format)`
thojanssens1

thojanssens1

So if Timex gives you the right time on the server for America/Denver (as you proved by opening an iex session on the server and show date with timex), then my next question would be:

  • Who sends this report? How is the sending triggered and at what time (and which time zone)?
  • Is the report pre-generated or generated at the same time it is sent?
travisf

travisf OP

I believe they are, isn’t RTC not being in UTC an evidence that they are? I’m not positive but that’s what I’m assuming.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New
csmr
Hi all, I’m new here and would like to hear peoples views on my Elixir/Phoenix based game-engine! :smiley: Mutonex gamedesign was finish...
New
perzanko
Do we have maintainer of absinthe-graphql/dataloader here? We have a PR that we’d like to merge to the library. Relatively small additive...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews