Commit Graph

64695 Commits

Author SHA1 Message Date
Pyre Bot Jr
b6af8df1a3 Add annotations to eden/fs/py/eden/thrift/windows_thrift.py
Reviewed By: xavierd

Differential Revision: D27846256

fbshipit-source-id: fed9073df58bd604ffeec2de93e0dd5e96930fb0
2021-04-19 09:19:20 -07:00
Stanislau Hlebik
5c7ff35af8 mononoke: copy bonsai changeset from prod repo to backup repo if they don't match
Summary:
To prevent bonsai changeset divergence between prod and backup repo by copying
bonsais from prod repo directly during hg sync job push.

See more details about motivation in D27824210

Reviewed By: ikostia

Differential Revision: D27852341

fbshipit-source-id: 93e0b1891008858eb99d5e692e4dd60c2e23f446
2021-04-19 09:00:11 -07:00
Stanislau Hlebik
13c207e28d mononoke: move create bonsai changeset hook to blobrepo_hg
Summary:
In the next diff it's going to be used to copy bonsais from the prod repo
during hg sync job, and in this diff I move this code to the common place so
that we can use it in the next diff

Differential Revision: D27852340

fbshipit-source-id: 9744571430e15a9d7f1e569d9b6690bc45787bd2
2021-04-19 09:00:11 -07:00
Stanislau Hlebik
eed5e12708 mononoke: add backup config to the config
Differential Revision: D27824210

fbshipit-source-id: bbef03c29281c4219484ce9993744a6467f0d207
2021-04-19 09:00:11 -07:00
svcscm svcscm
39cf65c8e5 Updating submodules
Summary:
GitHub commits:

5b89db8b7e

Reviewed By: yns88

fbshipit-source-id: d82253a359439eb68ec4b213eb5467b17845808e
2021-04-19 08:47:56 -07:00
Kostia Balytskyi
815b5ad04a megarepo_api: introduce a basic configo client
Summary:
This is not used on its on, but in subsequent diffs I will add a use-case, by
the megarepo configs crate.

When built in non-fbcode mode, this crate does not export anything. I chose this approach as opposed to the approach of exporting no-op stubs to force the clients to pay attention and implement gating their side too. This seems reasonable for a rather generic configo client.

Reviewed By: StanislavGlebik

Differential Revision: D27790753

fbshipit-source-id: d6dcec884ed7aa88abe5796ef0e58be8525893e2
2021-04-19 08:34:12 -07:00
Jan Mazur
c9205507d5 specify more counters to be bumped
Summary: More context in previous diff in the stack.

Reviewed By: krallin

Differential Revision: D27852299

fbshipit-source-id: dc06b29794d0c4e8ff6bf3f44507a64c06f01771
2021-04-19 05:49:05 -07:00
Kostia Balytskyi
d654ee8107 scs: change megaerpo parts of source_control.thrift
Summary:
This diff does the following:
1. makes `megarepo_add_sync_target` into an async call
2. wraps all the async call responses into an additional struct to convey the
idea of pending requests
3. fixes code which imports/implements these interfaces

1 is needed because adding a new target will need to create an initial state of
the megarepo (so not just write some configs), and that is an expensive
operation.

2 is needed because we don't want to express the idea of "this request is not
yet processed" through a thrift exception. Instead, let make `_poll` calls
return a struct with a single optional field. When present, that field will
contain the payload of response to the underlying request. When absent, it will
indicate the fact that the request is still pending.

Of course, this is a compatibility-breaking change, that's why I want to get it in as early as possible (while there are no real clients calling changed methods).

Reviewed By: StanislavGlebik

Differential Revision: D27823377

fbshipit-source-id: dc2a5ed327b38d1cacd575af9d7edf5768f9c377
2021-04-19 04:47:43 -07:00
svcscm svcscm
c8d6bd4309 Updating submodules
Summary:
GitHub commits:

1f3779e8a3

Reviewed By: yns88

fbshipit-source-id: 72fa12b4037c602c1b2a62b6663391fc82cc8338
2021-04-19 02:05:20 -07:00
Alex Hornby
43f8fbab26 rust: remove smallvec fork
Summary: Now we're on rustc 1.51 the fork is no longer needed.

Reviewed By: dtolnay

Differential Revision: D27827632

fbshipit-source-id: 131841590d3987d53f5f8afb5ebc205cd36937fb
2021-04-19 01:32:20 -07:00
Thomas Orozco
82991bd3fc mononoke/filestore: don't take a chunk when you need 0 bytes from it
Summary:
If you ask for a range starting at byte 3, and the chunks are of size 3, then
you don't actually need need the first chunk, but right now we'll fetch it
then extract zero bytes from it.

This is quite wasteful, and for LFS range fetches will be problematic since it
basically doubles the volume of stuff we need to keep in cache (we need both
chunks).

Reviewed By: farnz

Differential Revision: D27824411

fbshipit-source-id: 7103f5b4d5bb78f023245f3e8a1bcb0c2f28faab
2021-04-19 01:25:03 -07:00
Thomas Orozco
4a41242cd8 revisionstore: fix asking for chunks 1 more byte than configured
Summary:
Like it says in the title. We'd like to ask for the exact size that was
configured, because this way we can set the chunk size to the LFS threshold and
it avoids overlapping any file chunks server side.

Reviewed By: DurhamG

Differential Revision: D27824418

fbshipit-source-id: 43f40eb87080ec58e813ba1f1dda5b6a5e9f98ee
2021-04-19 01:25:03 -07:00
svcscm svcscm
a22a13731b Updating submodules
Summary:
GitHub commits:

bd022625a0
61e9f94478
8a3c99caed
badcb5f339

Reviewed By: yns88

fbshipit-source-id: 1bfb39e3c924b2423a9885fa005857fb53dd8419
2021-04-17 17:20:29 -07:00
svcscm svcscm
f73919fca0 Updating submodules
Summary:
GitHub commits:

ca3178682e
a4f3200127
20ee8879bc
4fa9932f00
1c0e8947e5
1692b02f91

Reviewed By: yns88

fbshipit-source-id: 30d2f94cc85625cf88b217e5df297ef2d4b542a8
2021-04-17 16:00:27 -07:00
svcscm svcscm
f0983c26cb Updating submodules
Summary:
GitHub commits:

8e2baf6151
e43f7174c9
70c0e3bb7b
1246915035
8cedd3daa0
0b553a7214
4fdec32e8c
94f513f711
840970f387

Reviewed By: yns88

fbshipit-source-id: a256abd59ba5466af80498c6745f7b2d60092eca
2021-04-17 13:01:40 -07:00
svcscm svcscm
5e555ee159 Updating submodules
Summary:
GitHub commits:

28664f5a4d
e9ca34b70f
e4f681e2f0
2c7947a6c4
7932fcef5b
32e83469a7
fcb32493e4
1c92971a24
f5e2ba3bad
20920adcc8

Reviewed By: yns88

fbshipit-source-id: f9cf71f11623889a78f70d0a05f3a6f1dbf95eca
2021-04-17 11:35:32 -07:00
svcscm svcscm
99dfccd7c9 Updating submodules
Summary:
GitHub commits:

7c86b9b486

Reviewed By: yns88

fbshipit-source-id: 78756e0436b75d7e370d30893d51f2ec1a18b707
2021-04-17 10:11:12 -07:00
svcscm svcscm
e044c63fbb Updating submodules
Summary:
GitHub commits:

23b19e61a5
0336a02507
1e2eea2b1e
afcf9dcf85

Reviewed By: yns88

fbshipit-source-id: e4b987ef8484db8ca6abc923c293ce2fa5dac948
2021-04-17 01:49:33 -07:00
svcscm svcscm
f67019096c Updating submodules
Summary:
GitHub commits:

7dce4aaa5a
4c02d129d7
25d62a05a2
1f2e4862a0
b43d3b789b
da1d16a510

Reviewed By: yns88

fbshipit-source-id: 5bae58820f35fde033ac817d4b2edbd7286e5f77
2021-04-17 00:30:40 -07:00
svcscm svcscm
7430c17607 Updating submodules
Summary:
GitHub commits:

c688849c19
772e002428
400b9bc91b
8fc31195cc
23e0abbb49
5fcde015e9
03f60cb88c
61c970858a
14fbbb7c37

Reviewed By: yns88

fbshipit-source-id: 709c757012deb3ea763fcc5850fcc4042ebfd08c
2021-04-16 22:53:44 -07:00
svcscm svcscm
ac94327b89 Updating submodules
Summary:
GitHub commits:

496e77ff63
054df58b82
581b635b71
27a992fb5c
531a5f88a1
b0dbf765b4
c2423987fa
4c0b2b5a27
70353c4594
136da7e551
48c4ffbbdf
88c5f51ebc

Reviewed By: yns88

fbshipit-source-id: dcb5ab49068130b56962eaf5e90dace02c5af4c0
2021-04-16 21:37:53 -07:00
svcscm svcscm
64f98fcb8a Updating submodules
Summary:
GitHub commits:

f9ed566e44
fd0bbd822b
d5d05c8dc9
a87085f262
1c19094293
997d3e7f9e
2af59bded1
4b731c1477
bb33aa30ba
8a524d5a0b

Reviewed By: yns88

fbshipit-source-id: a6a2035bd80652224fc11d3e51b4217792063f3a
2021-04-16 20:11:27 -07:00
svcscm svcscm
5752c29416 Updating submodules
Summary:
GitHub commits:

e23aad56c7
d9b7a39d42
2f1eb9fcb4
0119bcb851
046c16bb35
18782b554c
a37e4a0c07
303249168a
a0cf653140
c097d0d26c
753d0d314f
9adbf4e196

Reviewed By: yns88

fbshipit-source-id: 759c221bcfacdb802fc9fe4120f162ef57a8abf4
2021-04-16 18:54:23 -07:00
Xavier Deguillard
c1e940608f privhelper: do not make macOS NFS mount SOFT
Summary:
While soft mount are nice as they allow the server (edenfs) to die and the
client applications to not end up in D state, this also force a maximum
(non-configuerable) 60s timeout for all IOs, after which application receive a
ETIMEDOUT. Thus, we need to not make the mount hard, thankfully, since the
mount is INTR, applications should not stay in D state if EdenFS dies.

Reviewed By: genevievehelsel

Differential Revision: D27808311

fbshipit-source-id: 17c30e88e5b236418064d8c309d85fdc6f1ca3e9
2021-04-16 17:55:20 -07:00
svcscm svcscm
ac6ee95a69 Updating submodules
Summary:
GitHub commits:

9126c47b3e
65d58cd9a1
7bdad7a55f
b5e88664b5
c564b1bda2
cd7db13199
acea1a5852
bf4a9c76d5
7c04027ff1
523b3cf1fc
2fa32c1d34

Reviewed By: yns88

fbshipit-source-id: e1d89632d7ec1af1aeb12094ce5dfc59eb0d0c7c
2021-04-16 17:35:12 -07:00
svcscm svcscm
07ad3dd3bd Updating submodules
Summary:
GitHub commits:

fb77e24078
cfcbfd69b9
c547131beb
8496226c5a
10196d7edc
196bafa737
58c47faa2d
a4605fa0db
f9b43a2994
45c7d58e3a
e78d7457d2
3cf5ebf0b1
52d9d81e8f

Reviewed By: yns88

fbshipit-source-id: d43d0fbf24aa33365654618db8b30ef10c7bd345
2021-04-16 16:11:53 -07:00
svcscm svcscm
a972d1ec3f Updating submodules
Summary:
GitHub commits:

0f3e33e573
aecdff74c1
5463eac826
fc32eee35c
bad979b751
61fbf23b7e
3b3b9dc5a1
2c45783477
5ad84a136d
cb19231e5a
f5e0c15ffd
06fc1e0ada

Reviewed By: yns88

fbshipit-source-id: 61eb3d389d13b8ad532808cc26d96b08568275b1
2021-04-16 14:49:33 -07:00
svcscm svcscm
d929e43c43 Updating submodules
Summary:
GitHub commits:

66c7c048aa
e75c546d5a
0eff144f84
e370385aa5
8918117849
fca3f3e905
90e245697f
1414a720c1
ab54603c3d
45f11627e2

Reviewed By: yns88

fbshipit-source-id: 8b8cb95d4d86db23252839c40bb62f302cbff7f6
2021-04-16 13:34:50 -07:00
Thomas Orozco
2a3cec2dfa mononoke/changesets: add RendezVousConnection
Summary:
Like it says in the title, this includes rendezvous into changesets. This is
our busiest connection by far, and it is often hitting the limits of our
connection pool: https://fburl.com/ods/kuq5x1vw

Reviewed By: markbt

Differential Revision: D27794574

fbshipit-source-id: e2574ce003f12f6c9ecafd0079fe5194cc63c24b
2021-04-16 10:27:44 -07:00
Thomas Orozco
ff5ec32500 mononoke/changesets: express get() in terms of get_many()
Summary:
I'd like to add RendezVous here (because this is our busiest connection:
https://fburl.com/ods/6d4a9qb5), and it'll be easier to do so if I just have
one code path to change instead of two.

Reviewed By: farnz

Differential Revision: D27794575

fbshipit-source-id: 350e3f8e3f3a74cb7c675cef1264c8083c516480
2021-04-16 10:27:44 -07:00
Thomas Orozco
1ee93bdcfb mononoke/rendezvous: use in-flight connection count to decide when to batch
Summary:
After doing some local benchmarking (using MononokeApi instantiation as the
benchmark), one thing that's apparent is that we have quite a few parameters
here and that tuning them is likely to be a challenge.

One parameter in particular is the batch "objective", which controls how many
requests we want to see in the last batching interval before we choose to
batch (this is `rendezvous_dispatch_min_threshold`).

The problem with this is this is that there is no good, real-world, metric to
set it based on. This in contrast to the other parameters we have, which do
have some reasonable metric to compare to:

- rendezvous_dispatch_delay_ms: this is overhead we add to queries, so it
  should be small & on the order of query execution latency (i.e. a few ms).
- rendezvous_dispatch_max_threshold: this controls how big our batches get, so
  it should be on the order of what makes a SQL query too big (i.e. less than
  a hundred records).

In contrast, we want to set `rendezvous_dispatch_min_threshold` such that
batching kicks in before we start using too many concurrent connections (which
is what query batching seeks to reduce), but the problem is that those two
numbers aren't directly connected. One clear problem, for example, is that if
our DB is in-region vs. out of-region, then for a given query execution time,
and a desired concurrency level before batching kicks in, we'd need different
values of `rendezvous_dispatch_min_threshold` (it would have to kick in faster
for the out-of-region workload).

So, this diff updates rendez vou to actually track concurrent connection count
before we force batching. This is the actual metric we care about here, and it
has a pretty natural "real world" values we can look at to decide where to set
it (our connection pool — which is limited at 100 concurrent connections —, and
our open connection baseline).

Note: I set this at 5 because that's more or less what servers look like
outside of spikes for Bonsai hg mapping, and of Changesets where I'm planning to
introduce this in the future:

- bonsai: https://fburl.com/ods/6d4a9qb5
- changesets: https://fburl.com/ods/kuq5x1vw (note: to make sense of this,
  focus on just one server, otherwise the constnat spikes we get sort of hide
  the big picture).

Reviewed By: farnz

Differential Revision: D27792603

fbshipit-source-id: 1a9189f6b50d48444b3373bd1cb14dc51b85a6d2
2021-04-16 10:27:44 -07:00
Thomas Orozco
4130c60595 mononoke/cmdlib: remove public-facing add_scribe_logging_args API
Summary:
Like it says in the title. There's no reason for this to be ad ad-hoc "throw in
an arg" when everything else is done by adding arg types.

Reviewed By: HarveyHunt

Differential Revision: D27791333

fbshipit-source-id: 38e5a479800179b249ace5cc599340cb84eb53e2
2021-04-16 10:27:44 -07:00
Thomas Orozco
cf5b91ec95 mononoke/cmdlib: remove public-facing add_mcrouter_args API
Summary:
Like it says in the title. Let's remove ad-hoc "add an arg then look the arg"
mechanisms like this one.

Reviewed By: HarveyHunt

Differential Revision: D27791334

fbshipit-source-id: 257cea7763ab5130525ad739fe4ebdda4e8bfeb6
2021-04-16 10:27:44 -07:00
Thomas Orozco
b8f95fe3b0 mononoke/cmdlib: split args module
Summary:
This module is way too big and bundles many different functions:

- Our app builder
- Our matches object and environment initialization
- A bunch of utility functions

Let's split it up

Reviewed By: HarveyHunt

Differential Revision: D27790730

fbshipit-source-id: 8353b18a28fde5267d03ba0342c8cb98ad855e37
2021-04-16 10:27:44 -07:00
Thomas Orozco
c8cc339309 mononoke: remove parse_caching
Summary:
This isn't useful anymore. Let's ask our MononokeMatches what is set up for
caching instead of parsing the args one more time.

Reviewed By: HarveyHunt

Differential Revision: D27767697

fbshipit-source-id: 9da83769284a4aed4a96cd0eb212f42dd01ade87
2021-04-16 10:27:43 -07:00
Thomas Orozco
db4c509b9e mononoke: use MononokeEnvironment in RepoFactory
Summary:
There is a very frustrating operation that happens often when working on the
Mononoke code base:

- You want to add a flag
- You want to consume it in the repo somewhere

Unfortunately, when we need to do this, we end up having to thread this from a
million places and parse it out in every single main() we have.

This is a mess, and it results in every single Mononoke binary starting with
heaps of useless boilerplate:

```
    let matches = app.get_matches();

    let (caching, logger, mut runtime) = matches.init_mononoke(fb)?;

    let config_store = args::init_config_store(fb, &logger, &matches)?;

    let mysql_options = args::parse_mysql_options(&matches);
    let blobstore_options = args::parse_blobstore_options(&matches)?;
    let readonly_storage = args::parse_readonly_storage(&matches);
```

So, this diff updates us to just use MononokeEnvironment directly in
RepoFactory, which means none of that has to happen: we can now add a flag,
parse it into MononokeEnvironment, and get going.

While we're at it, we can also remove blobstore options and all that jazz from
MononokeApiEnvironment since now it's there in the underlying RepoFactory.

Reviewed By: HarveyHunt

Differential Revision: D27767700

fbshipit-source-id: e1e359bf403b4d3d7b36e5f670aa1a7dd4f1d209
2021-04-16 10:27:43 -07:00
Thomas Orozco
eba01d39e5 mononoke: move ScrubHandler out of ScrubOptions
Summary:
ScrubOptions normally represents options we parsed from the CLI, but right now
we abuse this a little bit to throw a ScrubHandler into them, which we
sometimes mutate before using this config.

In this stack, I'm unifying how we pass configs to RepoFactory, and this little
exception doesn't really fit. So, let's change this up, and make ScrubHandler
something you may give the RepoFactory if you're so inclined.

Reviewed By: HarveyHunt

Differential Revision: D27767699

fbshipit-source-id: fd38bf47eeb723ec7d62f8d34e706d8581a38c43
2021-04-16 10:27:43 -07:00
Thomas Orozco
c2c904f933 mononoke: initialize loggers, config, caching, tunables & runtime in MononokeMatches
Summary:
Basically every single Mononoke binary starts with the same preamble:

- Init mononoke
- Init caching
- Init logging
- Init tunables

Some of them forget to do it, some don't, etc. This is a mess.

To make things messier, our initialization consists of a bunch of lazy statics
interacting with each other (init logging & init configerator are kinda
intertwined due to the fact that configerator wants a logger but dynamic
observability wants a logger), and methods you must only call once.

This diff attempts to clean this up by moving all this initialization into the
construction of MononokeMatches. I didn't change all the accessor methods
(though I did update those that would otherwise return things instantiated at
startup).

I'm planning to do a bit more on top of this, as my actual goal here is to make
it easier to thread arguments from MononokeMatches to RepoFactory, and to do so
I'd like to just pass my MononokeEnvironment as an input to RepoFactory.

Reviewed By: HarveyHunt

Differential Revision: D27767698

fbshipit-source-id: 00d66b07b8c69f072b92d3d3919393300dd7a392
2021-04-16 10:27:43 -07:00
Thomas Orozco
9e92ba1d28 mononoke: always initialize tunables in integration tests
Summary:
We actually require tunables in our binaries, but some of our tests have
historically not initialized them, because the underlying binaries don't
load tunables (so they get defaults).

I'd like to remove the footgun of binaries not initializing tunables, but to do
this I need tunables to be everywhere, which is what this does.

Reviewed By: StanislavGlebik

Differential Revision: D27791723

fbshipit-source-id: 13551a999ecebb8e35aef55c0e2c0df0dac20d43
2021-04-16 10:27:43 -07:00
Thomas Orozco
3df7627d2d mononoke: rename MononokeEnvironment to MononokeApiEnvironment
Summary:
I want to call something else MononokeEnvironment (the environment the whole
binary is running in), so let's rename this one.

Reviewed By: StanislavGlebik

Differential Revision: D27767696

fbshipit-source-id: bd6f2f282a7fc1bc09926a0286ecb8a5777a0a24
2021-04-16 10:27:43 -07:00
Pyre Bot Jr
dc8edb9bd7 Add annotations to eden/fs/py/eden/thrift/test/client_test.py
Reviewed By: xavierd

Differential Revision: D27823522

fbshipit-source-id: 6bec6252e1c6f402528aed2ee784ba85373e6db3
2021-04-16 10:14:23 -07:00
Alex Hornby
072e871771 mononoke: log packblob test compressed sizes
Summary: This test failed on CI for unknown reasons,  log the sizes in the failure as a clue.

Reviewed By: farnz

Differential Revision: D27822287

fbshipit-source-id: d15c8165c1d5a5a588b48d7b8469e5cd9cba1a35
2021-04-16 08:34:19 -07:00
Jan Mazur
e885d25c86 use ErrorKind instead of generic ahyhow::Error to match on errors
Summary: Changing generic anyhow::Error to ErrorKind so there is no need to downcast when we want to match on errors.

Reviewed By: krallin

Differential Revision: D27742374

fbshipit-source-id: ba4c1779d5919eb989dadf5f457d893a3618fffc
2021-04-16 08:26:29 -07:00
Stanislau Hlebik
d93c5a3784 mononoke: add public phase warmer
Reviewed By: krallin

Differential Revision: D27821286

fbshipit-source-id: ece394a2f7f46a3b67d6074a615741c56dc7e3d8
2021-04-16 08:20:48 -07:00
svcscm svcscm
76a3055775 Updating submodules
Summary:
GitHub commits:

9ee9660e44
401e76e9e6
5c051ed675
27d39c9049
e61976ca83
2ed81908df
8ce4192225
358c035658
fb83c639ae
d72ae5499d

Reviewed By: yns88

fbshipit-source-id: eaf5b7e90c7cd6acedc24d533cb4c237cd9e4cef
2021-04-16 08:02:41 -07:00
Thomas Orozco
1367bb124f mononoke: "randomize" a few more queries
Reviewed By: StanislavGlebik

Differential Revision: D27821553

fbshipit-source-id: e5ebddfda7dc902efec0cf1a7924aa651b5cbc80
2021-04-16 07:11:52 -07:00
Simon Farnsworth
577d58ae72 Rearrange blobstore factory to ensure that PackBlob has a BlobstoreWithLink
Summary:
In the next diff, the packer will need to create PackBlobs with access to link and unlink operations on the underlying data store.

Rearrange blobstore factory so that this is guaranteed by design, noting that we will want to manually create just a PackBlob later.

Reviewed By: ahornby

Differential Revision: D27795485

fbshipit-source-id: e16c7baea4f2402a4f8f95d722adb5c422c5b8e3
2021-04-16 06:51:18 -07:00
svcscm svcscm
5bfda982de Updating submodules
Summary:
GitHub commits:

d3ddc64b6f
9a023a1d34
880b35e0b7
8c395224ca
9cb3c09e5e
4c41e51c07
a032870708
70835f3858
f4c2f9d036
fe6be75b79
f6c0232d78
7c0b2bb1f1
ff7bc1081b

Reviewed By: yns88

fbshipit-source-id: fdceffb41f43f1aa2dcc791ff4c60f876aa78237
2021-04-16 06:45:52 -07:00
svcscm svcscm
3f2ddeee53 Updating submodules
Summary:
GitHub commits:

3cb38fd0fb
d68838f2a1
842cc1dbab
a3c1fac8eb
7843439a19
2825c959ed
e0a8f18fad
c806f5f3fb
0a5a997fa2
973db55be4
ff558e648a
8ab002d154

Reviewed By: yns88

fbshipit-source-id: 12b4bb34b266a9c3dbe1289452263dc15b41f104
2021-04-16 03:36:30 -07:00
Jan Mazur
77a205db89 quiet certain connection errors when shutting down
Summary: Similar to D27155123 (1a56da1c6f).

Reviewed By: krallin

Differential Revision: D27805926

fbshipit-source-id: cf58a2e9b2ef92ca536f3b61b63fb42cfb1ec940
2021-04-16 02:26:04 -07:00