Activity Graph

Page 1 of 11 | Next »


[12:06:01] benwilson512: hey Mieserkadser
[12:06:16] benwilson512: Mieserkadser: is the menu rendered with javascript?
[12:06:40] benwilson512: or manipulated by javascript?
[12:07:10] benwilson512: oh I see so, when you click on a menu item it changes the whole page
[12:07:14] benwilson512: which basically closes the menu
[12:07:19] benwilson512: and you want to keep the menu open?
[12:08:32] benwilson512: Mieserkadser: yeah that's a tricky question. you've got a few choices as far as I can see
[12:10:11] benwilson512: Mieserkadser: one would be to try to push the menu state to the next page so that it can render the menu correctly. You could achieve this by using phx-hook to stash the menu state in a javascript variable, and then if you use live_redirect to change the page, you should still have the js variable value around
[12:10:25] benwilson512: and when the menu mounts you could push it to the server to set the menu correctly
[12:11:23] benwilson512: option two would be to have the main page content as an independent live view that gets switched out depending on the menu option chosen. I'm not sure how that would work with url paths though
[12:11:44] benwilson512: JS state probably requires the least re-work of things
[12:11:56] benwilson512: well, it doesn't have to
[12:12:05] benwilson512: a live_link doesn't full page load
[12:12:31] benwilson512: with phx-hook though you could even shove menu state in local storage
[12:12:43] benwilson512: and then whether you full page load or not it's still there
[12:14:34] benwilson512: Mieserkadser: good luck!
[12:41:46] benwilson512: you also have to avoid things that use NIFs, although this is easier in erlang / elixir than a lot of other languages which tend to drop down to C a fair bit for common libraries
[13:20:01] benwilson512: hauleth: I think the argon2 backend for that has a pure elixir implementation
[13:20:29] benwilson512: r00tl3ss: and those of us using docker may as well just bundle erts
[13:21:53] benwilson512: hauleth: ah it's
[13:22:43] benwilson512: I picked when doing the Absinthe book because I didn't want to have to debug people's NIFs failing to compile ;)
[13:29:13] benwilson512: hauleth: yeah perfectly fair, I wouldn't use it in production either
[13:29:34] benwilson512: I figured it was a good enough balance between "realistic" and "I don't want to debug C build chains" for book purposes
[14:28:47] benwilson512: Mieserkadser: wonderful!
[14:29:12] benwilson512: Mieserkadser: where did you stash the menu state in the end? javascript variable or local storage?
[19:05:25] benwilson512: Dakora: as in, mix isn't even in the release
[19:05:52] benwilson512: if the release is using dev configuration
[19:06:02] benwilson512: make sure you're running the release that's in _build/prod
[19:06:13] benwilson512: if you're using distillery
[19:06:23] benwilson512: make sue you're doing release --env=prod
[19:09:51] benwilson512: Dakora: show your prod.exs and release.exs
[19:10:41] benwilson512: normally you don't want to specify config environment variables when you build your release
[19:10:45] benwilson512: it should be independent of all of that
[19:10:51] benwilson512: and then you supply them when you run the release
[19:11:05] benwilson512: suplying the mix env when you run the release is pointless, mix is gone after the release is built
[19:13:33] benwilson512: do you have a release.exs?
[19:13:58] benwilson512: yeah I mean it's new in 1.9
[22:35:23] benwilson512: josevalim: I mentioned that phoenix_ecto sandbox via user-agent header is awesome


[12:21:59] benwilson512: Miyu-chan: to be clear, those are build time dependencies
[12:22:55] benwilson512: unless you're serving production traffic from your laptop I'm not clear on what the security risk is
[12:23:16] benwilson512: and as noted, this isn't related to phoenix at all, phoenix doesn't have an asset pipeline, it's all webpack
[12:23:59] benwilson512: that's correct, which phoenix hands off to standard JS tooling
[17:18:21] benwilson512: greenail: no there is no guard for that
[17:18:26] benwilson512: anything can be a stream
[17:18:30] benwilson512: if it implements the enumerable protocol
[18:04:23] benwilson512: Dakora: yeah make sure your sshd has the key already setup
[18:04:26] benwilson512: ssh-add path/to/key
[18:08:08] benwilson512: Dakora: dunno, I've never not had an auth agent
[18:10:09] benwilson512: Dakora: do you type in your password every time you do a git operation?
[18:10:14] benwilson512: that uses a remote?
[18:10:49] benwilson512: I think I'd lose my mind
[18:54:59] benwilson512: lizzin: yeah use Registry and some other identifier


[14:35:44] benwilson512: supitto: you can use
[14:35:53] benwilson512: to see if `A` has the function, and if it does call it, otherwise call B
[14:38:19] benwilson512: supitto: without explicitly doing so in C.somefun?
[14:38:34] benwilson512: this seems like you're trying to do an implicit module inhertance scheme
[14:38:57] benwilson512: I'm sure there's some way to do it with macros but I'd suggest re-approaching the problem to avoid this need
[14:39:57] benwilson512: sure, but there are lots of ways to do that
[14:40:07] benwilson512: usually this means that `somefun` is doing too much
[14:49:08] benwilson512: supitto: sure one sec
[14:50:21] benwilson512: so to make sure I understand this correctly
[14:50:50] benwilson512: which of these supports reads and which supports rights?
[14:51:39] benwilson512: how do you pick amongst the N slaves for a given read?
[14:52:56] benwilson512: I see. so, at a minimum I'd probably want to be explicit about whether I was doing the master or the slave
[14:53:10] benwilson512: and not dispatch that magically inside Repo
[14:53:32] benwilson512: if you dispatch behind the scenes, certain code may not behave the way you think
[14:53:44] benwilson512: Repo.insert(%User{id: 1}); Repo.get!(User, 1);
[14:53:47] benwilson512: the `get!` may fail
[14:53:54] benwilson512: if the replica is behind the master
[14:54:26] benwilson512: it's clearer that this may happen if you have Repo.Writer.insert(%User{id: 1}); Repo.Replica.get!(User, 1);
[14:55:06] benwilson512: more to the point, if you want people to treat writes differently than reads, you want the code to communicate that
[14:56:08] benwilson512: code that queries in order to do writes probably _should_ query the master
[14:56:21] benwilson512: code that is merely read only should hit the replicas
[14:56:48] benwilson512: it's worth being explicit about that
[15:10:59] benwilson512: supitto: ouch yeah that's a lot of uses


[15:28:35] benwilson512: josevalim: isn't the order scrambled from the seed?
[15:28:40] benwilson512: or is that only for tests within a given file?
[15:29:32] benwilson512: gausby_: notably, if your tests use the ecto sandbox, such dependence is virtually impossible anyway, since tests cases are entirely isolated. but yea as Jose notes, it's already scrambled
[15:31:22] benwilson512: josevalim: tangentially, phoenix_ecto's built in sandbox plug is incredible, we've got that working from hound => elixir UI service that doesn't even have ecto => graphql calls to our CI instance running phoenix_ecto sandbox
[15:32:02] benwilson512: means we can do proper integration tests at the CI level, and locally, all against a single application instance, without stomping on each other. it's a dream
[16:27:41] benwilson512: icecreamcohen: on a call, back in a few
[16:32:02] benwilson512: icecreamcohen: what's up?
[16:34:54] benwilson512: icecreamcohen: totally understood
[16:35:05] benwilson512: icecreamcohen: so, when you say query, do you mean "inside a request" ?
[16:35:12] benwilson512: cause `query` the graphql operation type
[16:35:23] benwilson512: and `query` the "request" get overloaded in meaning a bit
[16:35:37] benwilson512: right so operation types are top level
[16:35:46] benwilson512: none of them nest in each other
[16:36:06] benwilson512: and a given document can only have one operation specified to be executed
[16:36:13] benwilson512: if so it's probably a bug then
[16:36:52] benwilson512: I mean the spec allows for exactly one operation within a given "document" to be executed. You can execute a batch of documents but
[16:36:58] benwilson512: query { mutation { } } has no meaning
[16:37:08] benwilson512: if absinthe supports that, then that's a bug
[16:38:31] benwilson512: there is a RootQueryObject, RootMutationObject, and RootSubscriptionObject, which you access via the query, mutation, and subscription operation types respectively
[16:38:49] benwilson512: what type does `currentLocation` return?
[16:39:13] benwilson512: Absinthe has no way of stopping you from doing side effects
[16:40:33] benwilson512: "mutations" are only those fields that sit on the root mutation object
[16:40:44] benwilson512: mutation { sendLocationSms() }
[16:40:49] benwilson512: would be the traditional way to do that
[16:40:58] benwilson512: don't think in terms of objects and methods that mutate those objects
[16:41:17] benwilson512: it's a bit more CQRS style, where you have a set of commands or mutations your API responds to
[16:41:39] benwilson512: which take some parameters and return a value that you can query to see the effect of your mutation
[16:45:40] benwilson512: no problem! As far as API design goes, Absinthe relies on the book, and general community literature for guidance
[16:45:59] benwilson512: since good design principles for your GraphQL API are not really language specific
[16:50:21] benwilson512: icecreamcohen: it's a reasonably common mistake I think for people coming from REST, where the entity is primary
[16:50:24] benwilson512: and everything hangs off of that
[16:52:11] benwilson512: icecreamcohen: in our experience, as we got more comfortable with GraphQL, our mutation field names became more command / event oriented. So instead of createOrder, updateOrder(state: "fulfilled") we'd have placeOrder, fullfillOrder, tec
[16:52:41] benwilson512: makes subscriptions easier too, since subscriptions are basically subscribing to those events happening
[16:54:09] benwilson512: icecreamcohen: that's perfectly fine, Absinthe lets you broadcast out of band
[16:54:20] benwilson512: but it's helpful if you think of it that way
[16:54:42] benwilson512: good luck! I've gotta run but I'll be around later if you hit further snags
[20:02:25] benwilson512: chrismccord: ping
[20:02:32] benwilson512:
[20:02:38] benwilson512: when it has session: %{user_id:}
[20:02:45] benwilson512: how is that transmitted? cookie?
[20:04:52] benwilson512: if you're using live routes, what's the equivalent mechanism? The :session key on the live route grabs items out of the plug session, and you can get path params
[20:05:21] benwilson512: but what I'd love is the ability to have a function that takes a plug, and returns a live view session map
[20:05:34] benwilson512: if such a thing exists outside of the dedicated render calls, I'm missing it
[22:35:08] benwilson512: josevalim: chrismccord yes that's correct. right now if I have values that I have on the conn assigns that I want to make available in the live view, I have to put them on the plug session, which is weird, since that's persisted in a cookie
[22:35:50] benwilson512: josevalim: as I understand it, values passed in `live_render(foo, session: session)` are merely embedded in the DOM, they are not set on the plug session, and thus aren't persisted in the cookie
[22:44:58] benwilson512: TL;DR: there is a plug session, and there is a live view session. When you use live_render, you can explicitly manipulate the live view session. When using live routes, you can't (AFAIK), you have to manipulate the plug session, but this has the side effect of setting a cookie, which is undesirable.
[23:21:13] benwilson512: josevalim: OK, so the methods for getting data into a live view are
[23:21:27] benwilson512: cookie, connection params, path params, query params
[23:22:13] benwilson512: specifically, these are the only methods that get data in to the `mount` function
[23:22:23] benwilson512: so exclude query params from that list


[20:53:46] benwilson512: icecreamcohen: what's the downside to nimbleparsec?
[20:54:07] benwilson512: it's pretty easy to use, and the code it generates is quite optimal
[20:58:42] benwilson512: yeah the absinthe one is complex too, but to be fair so was the leex solution


[15:02:06] benwilson512: we're doing that
[15:08:18] benwilson512: nickjj: it is not sorry
[15:10:37] benwilson512: it's basically just worked from day one. as far as performance goes, that's largely a function of what you're doing with the live view
[15:10:56] benwilson512: liveview has basically two costs associated with it
[15:11:09] benwilson512: memory to handle the active connection, and then the render CPU time
[15:12:22] benwilson512: nickjj: that should be fine, if you think about it it's not really any more work than you'd have with a static view generally, you just don't need to re-establish the connection
[15:12:35] benwilson512: the only constraint from there is memory for the active connections, which is pretty easy to manage
[15:12:41] benwilson512: and also quiet low
[15:13:02] benwilson512: the new feature where assigns can be marked temporary or w/e helps with that a lot
[15:22:47] benwilson512: nickjj: yeah should be totally fine
[15:49:56] benwilson512: System.cmd("ping", [""])
[20:39:34] benwilson512: longtomjr: you can use an anonymous function
[20:39:50] benwilson512: Keyword.update(list, :key, fn value -> value * 2 end)
[20:44:23] benwilson512: longtomjr: ah for that you want!/3
[20:45:29] benwilson512: longtomjr: what do you want it to do
[20:45:31] benwilson512: add the value?
[20:45:33] benwilson512: or do nothing
[20:45:45] benwilson512: oh that's just Keyword.put then
[20:46:25] benwilson512:
[23:10:11] benwilson512: OliverMT: like if you have mutation { foo1: createFoo(), foo2: createFoo() } ?
[23:10:35] benwilson512: hypercore: remote_console
[23:14:04] benwilson512: hypercore: app/bin remote_console
[23:14:15] benwilson512: I don't know if edeliver has a command for it, I've never used it sorry
[23:24:19] benwilson512: hypercore: uh does the rest of the site work?
[23:28:51] benwilson512: hypercore: yeah that probably crashed the repo
[23:29:02] benwilson512: hypercore: I'd consider just nuking the database and starting over if you dont' have any valuable data


[19:16:43] benwilson512: gamache: sounds like they should be a dependency in package.json
[19:21:26] benwilson512: gamache: you don't have an asset build step at all?


[14:59:58] benwilson512: chrismccord: saw your talk, great stuff. did the CSRF token stuff make it into the hex release?
[15:00:16] benwilson512: trying to sort out if I can move off of our fork
[16:20:51] benwilson512: josevalim: yeah no worries, I added a WIP PR which is mostly gated on error messaging and docs
[16:26:32] benwilson512: will continue to work off of our fork which I rebased off master


[11:58:58] benwilson512: just set up a copy of our app in sandbox mode in staging so we can run UI tests in CI/ locally, works super well
[11:59:11] benwilson512: only realized yesterday that that ships with phoenix_ecto
[11:59:23] benwilson512: very easy to use
[12:04:09] benwilson512: rawtaz: ecto sandbox testing via the API
[12:04:26] benwilson512: rawtaz: when doing normal ecto tests, you get a nice sandboxed connection per test case
[12:04:39] benwilson512: every test is isolated, and can be concurrent
[12:05:06] benwilson512: suppose you want to run integration tests in your mobile app and / or your UI framework, or some other Elixir application
[12:05:24] benwilson512: phoenix_ecto sandbox plug provides a /sandbox path you hit at the start of each test case
[12:05:47] benwilson512: and then you send the returned value as a header in all subsequent calls within the mobile app / ui test case
[12:06:07] benwilson512: and when you do that you get the same isolation and concurrent test properties that you have within a normal ecto test
[12:06:49] benwilson512: well, that's certainly what I'm using it for, I think there are some IIRC that's also where the protocol impl for changesets and forms lives
[12:07:34] benwilson512: rawtaz: and to be clear, the regular getting started stuff w/ phoenix does include phoenix_ecto
[12:08:45] benwilson512: rawtaz: I just now realized that it included the sandbox plug
[12:10:04] benwilson512: because of that, I have a single instance of my app up in our staging environment, and yet I can run tests on our CI, and locally, and on someone else's computer _at the same time_ and none of them conflict w/ each oehr
[12:26:47] benwilson512: yeah, so if I have some phoenix service A, and then some separate codebase B in whatever language you want
[12:27:01] benwilson512: you can have A run in a mode that exposes /sandbox
[12:27:11] benwilson512: and then tests in B that hit /sandbox to get basically a token
[12:27:23] benwilson512: and then every other request from B to A in B's test cases pass in that token as the user agent header
[12:27:31] benwilson512: you can totally do this concurrently
[12:28:17] benwilson512: hitting /sandbox returns a value that corresponds to a genserver
[12:28:26] benwilson512: each test case would get a different value
[12:28:49] benwilson512: it's the same mechanism that lets you do that with ecto
[12:29:40] benwilson512: hitting /sandbox returns a token. every request made with that token is isolated from every other request, EXCEPT requests made with the same token
[12:30:59] benwilson512: so, if you have two test cases in B and they each hit /sandbox at the start, they'll get different tokens, and as long as they consistently use those tokens over the course of the respective test cases, the two test cases never affect each other. that isolation does not depend on them happening serially
[12:31:09] benwilson512: these aren't auth tokens
[12:31:45] benwilson512: to be clear, I'm not running A's tests
[12:31:53] benwilson512: i'm running B's tests, where A acts like a database
[12:32:25] benwilson512: and you don't have to clean up afer
[12:33:30] benwilson512: in an analogous way to A's tests being able to hit postgres concurrently and yet isolated, this let's B hit A in a way that is both concurrent and isolated
[16:16:15] benwilson512: T0pHat: depends on what you mean by implements
[16:16:27] benwilson512: T0pHat: optimistic locking is absolutely a thing you can use with ecto
[16:17:49] benwilson512: yes it UPDATE WHERE
[16:17:58] benwilson512: The operative part is "then checking whether another user has made changes to the record only when updating the record. "
[16:18:34] benwilson512: you can validate this by setting the log level to debug, and you'll see the expected SQL
[18:50:59] benwilson512: keden: you may want to try out
[18:51:42] benwilson512: it's like heroku in that it aims to be extremely easy to use, but it's also aimed specifically at Elixir apps, which can make it easier to take advantage of some of Elixir's specific features that aren't as easy on heroku
[18:51:59] benwilson512: Heroku is honestly not a bad option however, I think Elixir's package manager (written in Elixir) is hosted on heroku


[15:48:01] benwilson512: josevalim: if sharing is expanded that will definitely negatively impact structs that go in ets, since that negates the work done to have structs utilize sharing
[15:52:12] benwilson512: garazdawi: right, so what I'm seeing on my end is a term with a flat size of 6k, that when inserted into ets the `:erlang.memory(:ets)` grows by 50k
[15:52:28] benwilson512: I'll create a runnable example
[15:59:07] benwilson512:
[15:59:16] benwilson512: runnable with `elixir ets_memory.exs`
[15:59:23] benwilson512: josevalim: garazdawi ^^
[15:59:57] benwilson512: the flat size of the list of 1000 atoms is 2000 words, the ets memory growth per insertion is 16k words
[16:01:04] benwilson512: this is not effected at all by the actual text of the atom at least
[16:01:53] benwilson512: nor does changing the ets table from :duplicate_bag to :set change anything (assuming you also make the change of doing `:ets.insert(table, {i, value})`)
[16:14:00] benwilson512: well, that's embarassing
[18:39:55] benwilson512: OliverMT: well in my defense I was also getting bitten by some of the sharing nuances, but the whole confusion between words and bytes definitely created some confusion when I tried to isolate the sharing issue
[18:42:10] benwilson512: if you go to the search there is a great place if you're just looking for a function by name. Within VSCode the ElixirLS extension does a great job of associating docs to functions even from libraries
[18:42:18] benwilson512: you can even "Go to definition" with phoenix functions
[18:51:21] benwilson512: it needs to take a few minutes to compile the project and dependencies
[18:51:31] benwilson512: maybe that's it
[18:57:41] benwilson512: namosca: I don't recall needing to, I'd double check the elixirls vscode configuration and make sure things look right. maybe the way you open it matters too
[18:57:46] benwilson512: namosca: I always open VScode by doing `code .` from within my project directly
[22:07:59] benwilson512: anyone ever run into " Overlay failed, illegal operation on a directory" with distillery before?
[22:08:33] benwilson512: trying to setup a post start hook