Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • May 19 15:23
    ioleo closed #156
  • May 19 15:23
    ioleo commented #156
  • May 19 15:01
    cornerman commented #156
  • May 19 14:59
    cornerman commented #156
  • May 19 09:12
    ioleo opened #156
  • May 01 07:10
    mergify[bot] closed #155
  • May 01 07:10

    mergify[bot] on master

    Update chameleon to 0.3.5 (#155) (compare)

  • May 01 07:08
    mergify[bot] labeled #155
  • May 01 07:08
    scala-steward opened #155
  • Apr 25 13:26

    mergify[bot] on master

    Update sbt-tpolecat to 0.3.1 (#… (compare)

  • Apr 25 13:26
    mergify[bot] closed #154
  • Apr 25 13:24
    mergify[bot] labeled #154
  • Apr 25 13:23
    scala-steward opened #154
  • Apr 25 11:08

    mergify[bot] on master

    Update sbt-scalajs, scalajs-com… (compare)

  • Apr 25 11:08
    mergify[bot] closed #149
  • Apr 25 11:06
    mergify[bot] synchronize #149
  • Apr 25 11:06
    mergify[bot] commented #149
  • Apr 25 11:05
    cornerman commented #149
  • Apr 25 10:23

    mergify[bot] on master

    Update scalatest to 3.2.12 (#15… (compare)

  • Apr 25 10:23
    mergify[bot] closed #153
nafg
@nafg
This message was deleted
I see it comes back to ClientImpl#execute taking R
johannes karoff
@cornerman

How can I write an implementation that returns a Result[T] when I don't know what T is

You get the current result Result[T]. I thought it would make sense for IO or Task, where then can map over the result and return the new one with logging

nafg
@nafg
Yeah I guess I'm probably abusing LogHandler
johannes karoff
@cornerman

I see it comes back to ClientImpl#execute taking R

exactly! We get the the result R wrapped in Result[R], so I need to pass the around :)

nafg
@nafg
Either that or did something wrong.
To be clear the T is the deserialized response from the request?
johannes karoff
@cornerman
Yes!
nafg
@nafg
Ok I misunderstood when I migrated to 0.1.0 it seems
johannes karoff
@cornerman
Feel free to share your code, maybe we can fix it
nafg
@nafg
Before that I had
    override def logRequest[R[_], ErrorType](path: List[String], argumentObject: Product, result: R[_])
                                            (implicit monad: MonadError[R, _ >: ErrorType]) =
so I thought that you moved R out to the trait and what remained was ErrorType
of course that can't be because result is now Result[T]
but I didn't think into it I guess
johannes karoff
@cornerman
I moved the Errortype out of the method, because you would not know what it is. and the monad error was there to actually do something with the Result R[_], but actually you do know your Result{_]and therefor your ErrorType
nafg
@nafg
yeah
I think I'm good now
johannes karoff
@cornerman
Great!
What I do not like about the logRequest is that you actually have to come up with a way to log (stringify) it, so there is only toString or pattern matching. Not sure what could be a better approach.
nafg
@nafg
Well what purpose does it serve, precisely?
i.e. what are the motivating use cases
johannes karoff
@cornerman
The purpose is to enable centralized logging in the client. The router is typically on the backend and you have ways to log your requests between your, e.g., http-api and calling the router. But in the client, you might use Future or Task or your result type. So in order to not do the logging on each method call, you can define the loghandler through which all requests with their results go.
Is is empty by default and does nothing, but it makes sense for some applications.
nafg
@nafg
What I mean is, what would I want to log and why?
My use case for extending it was to log failures
But when would I want to log the response object
moritz bust
@busti
Why does Request use List for it's path?
Isn't Seq more appropriate, or does it explicitly require linked list capabilities?
moritz bust
@busti
Also, is #12 rebased onto the 2.13 update?
johannes karoff
@cornerman
@Busti Yes, i rebased #12 on top of the current master
Currently, we pretty much just use the request path List with two strings (the trait name and the method name). See: https://github.com/cornerman/sloth/blob/master/sloth/src/main/scala/Router.scala#L13
@nafg I currently use the logger only for development and debugging. So, in development I have debug logs in the LogHandler and in production the LogHandler is empty. Otherwise, I agree with you - you normally want to log failures.
nafg
@nafg
Thank G-d, I've finally solved the slow compile times
All it took was avoiding full auto derivation using shapeless, by writing magnolia derivers that respect existing instances
I can share the code later
Kenner Stross
@kennerstross
Hello. I've been using covenant and sloth to manage my client/server interactions in a Scala 2.12 / Scala JS 0.6.x environment. Now... for various reasons, I must move to Scala JS 1.x, but it doesn't look like there are covenant/sloth versions for 1.x, which leaves me high-and-dry. Any suggestions? What are others doing in this situation? Thanks in advance for any advice you have.
johannes karoff
@cornerman
@kennerstross Hi there! There was work done on it, but currently an optional dependency in chameleon hinders a merge of the PR: cornerman/sloth#55
We need to wait for an issue in the boopickle release.
Alternatively, we could split up chameleon into multiple projects (for each dependency instead of having one release with optional dependencies). And in sloth only depend on the core types. Then we could make this faster.
Kenner Stross
@kennerstross
Thanks for the response, @cornerman. Personally, I would love to see the split approach!
johannes karoff
@cornerman
@kennerstross I will see whether I can do it soonish - I do not have so much time as of right now. Otherwise a PR would be awesome.
johannes karoff
@cornerman
@kennerstross This issue has been fixed by the way. You can use sloth now with scalajs 1.x with sloth version 0.3.0.
Kenner Stross
@kennerstross
Thanks, @cornerman !
Marc Grue
@marcgrue

I have been strugling to find a way to receive failed Futures (with exceptions) with RPC and Akka-Http / Sloth / Boopickle and therefore made a minimal project to test with the following commands:

git clone https://github.com/marcgrue/scalajs-rpc-exception-test.git
cd scalajs-rpc-exception-test
sbt rpcJVM/run

And in another process

sbt test

Maybe the problem is not related to Sloth but rather Boopickle or my Akka-Http setup. I would be most gratefull if someone could give me a hint... Thanks in advance!

nafg
@nafg
@marcgrue what is the issue?
Marc Grue
@marcgrue
@nafg The issue is that I can't return a failed Future with an expected exception when testing an api.
nafg
@nafg
Why not?
Marc Grue
@marcgrue
Because the exception is deserialized to a single byte (the boopickle index of the specific exception) here
Marc Grue
@marcgrue

I found the problem! Project is update and everything works now. The reason, only a single Byte was de-serialized was that I took a serialized failed future (with an exception) and tried to de-serialize it to the return type of the API method which in this case was an Int. The response data from the Ajax call needs to be de-serialized with either the API method result type T OR Throwable for serialized failed futures!

To determine whether serialized data is of a successful or failed future, one could try to unpickle it with Throwable to see if boopickle recognized it as so, and then otherwise unpickle with the API method return type. But that would require to duplicate the ByteBuffer to avoid a BufferUnderflowException (consume it twice) which is of course a bad idea. I tried to send a response head with a exception-or-not flag but didn't get that to work. So I went for a bit of a hack by adding a byte of 0 or 1 to the beginning of the ByteBuffer so the client can know which type of de-serializing should be done.

My problem didn't show up in the Sloth tests since they don't use Ajax which requires both successful and failed futures to be serialized with the same PickleType (in this case ByteBuffer) but de-serialized with T or Throwable. @cornerman - it might be worth to mention in your readme (unless I have missed to do it the right way :-)

johannes karoff
@cornerman

Hi @marcgrue, sorry for answering so late to your question. First of all, thank you for setting up this example!

You are right, sloth does not directly support you when you want transport a failure in your F[_] type of the router and client. So somehow signaling the error in the protocol in your router and client is correct. Though, in this case, you could also make use of the HTTP status code. Like a 200 means success and you can just return it. And a status code like 404 or 400 or 500 could mean that you have a pickled exception.

Another approach is to move the error from the F[_] type into the method in question. Like:

trait Api[F[_]] {
  def something: F[Either[Throwable, Int]]
}

Thereby, the router will actually serialize the throwable just as expected. And the client can use it. But that of course means, that you need to handle it on the client side explicitly.