New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove try/catch semantics in otherwise pure code #1592

Merged
merged 9 commits into from Dec 22, 2017

Conversation

Projects
None yet
4 participants
@jmcardon
Member

jmcardon commented Dec 11, 2017

Handling #1578 and cleaning up code in general.

@jmcardon jmcardon requested a review from rossabaker Dec 14, 2017

Show outdated Hide outdated client/src/main/scala/org/http4s/client/Client.scala Outdated
Show outdated Hide outdated core/src/main/scala/org/http4s/EntityDecoder.scala Outdated
Show outdated Hide outdated core/src/main/scala/org/http4s/util/package.scala Outdated
Show outdated Hide outdated core/src/main/scala/org/http4s/MessageFailure.scala Outdated
} catch { case t: Throwable => handleException(t); facc }
}
.apply(newReq)
.getOrElse(Vector.empty[PushResponse[F]])

This comment has been minimized.

@rossabaker

rossabaker Dec 15, 2017

Member

I'm trying to think what exception here we were motivated to catch in the first place.

@rossabaker

rossabaker Dec 15, 2017

Member

I'm trying to think what exception here we were motivated to catch in the first place.

This comment has been minimized.

@jmcardon

jmcardon Dec 15, 2017

Member

I Don't think this one is doing anything in particular.. its removal didn't break anything.

@jmcardon

jmcardon Dec 15, 2017

Member

I Don't think this one is doing anything in particular.. its removal didn't break anything.

This comment has been minimized.

@rossabaker

rossabaker Dec 16, 2017

Member

Kill it.

@rossabaker

rossabaker Dec 16, 2017

Member

Kill it.

@@ -96,18 +96,11 @@ class Http4sServlet[F[_]](
request: Request[F],
bodyWriter: BodyWriter[F]): F[Unit] = {
ctx.addListener(new AsyncTimeoutHandler(request, bodyWriter))
// TODO: This can probably be handled nicer with Effect
// Note: We're catching silly user errors in the lift => flatten.

This comment has been minimized.

@rossabaker

rossabaker Dec 15, 2017

Member

This is a case where I'd be happy to lecture about the silliness.

There is a similar construction in the blaze Http1ServerStage.

@rossabaker

rossabaker Dec 15, 2017

Member

This is a case where I'd be happy to lecture about the silliness.

There is a similar construction in the blaze Http1ServerStage.

This comment has been minimized.

@jmcardon

jmcardon Dec 16, 2017

Member

the one in the Http1ServerStage is of the form:

  executionContext.execute(new Runnable {
          def run(): Unit =
            F.runAsync {
                try serviceFn(req)
                  .getOrElse(Response.notFound)
                  .handleErrorWith(serviceErrorHandler(req))
                catch serviceErrorHandler(req)
              } {
                case Right(resp) =>
                  IO(renderResponse(req, resp, cleanup))
                case Left(t) =>
                  IO(internalServerError(s"Error running route: $req", t, req, cleanup))
              }
              .unsafeRunSync()
        })

This is similar to writing fs2.async.unsafeRunAsync(F)(callback) but with the exception that F.shift(ec) submits a task onto the execution context.

Maybe im being a paranoid panda but while the ServerStage1 is uglier, it might be more efficient (In a sense, it's not submitting a useless task like the shift method does to evaluate the continuation) and I'm afraid of a tiny performance regression because of a change there.

Shift defined (In IO) as:

  def shift(implicit ec: ExecutionContext): IO[Unit] = {
    IO async { (cb: Either[Throwable, Unit] => Unit) =>
      ec.execute(new Runnable {
        def run() = cb(Right(()))
      })
    }
  }

I actually could see what's on master to be more efficient, albeit ugly to look at.

Just my 2 cents. I'm probably microoptimizing for nothing so a second perspective would be nice.

@jmcardon

jmcardon Dec 16, 2017

Member

the one in the Http1ServerStage is of the form:

  executionContext.execute(new Runnable {
          def run(): Unit =
            F.runAsync {
                try serviceFn(req)
                  .getOrElse(Response.notFound)
                  .handleErrorWith(serviceErrorHandler(req))
                catch serviceErrorHandler(req)
              } {
                case Right(resp) =>
                  IO(renderResponse(req, resp, cleanup))
                case Left(t) =>
                  IO(internalServerError(s"Error running route: $req", t, req, cleanup))
              }
              .unsafeRunSync()
        })

This is similar to writing fs2.async.unsafeRunAsync(F)(callback) but with the exception that F.shift(ec) submits a task onto the execution context.

Maybe im being a paranoid panda but while the ServerStage1 is uglier, it might be more efficient (In a sense, it's not submitting a useless task like the shift method does to evaluate the continuation) and I'm afraid of a tiny performance regression because of a change there.

Shift defined (In IO) as:

  def shift(implicit ec: ExecutionContext): IO[Unit] = {
    IO async { (cb: Either[Throwable, Unit] => Unit) =>
      ec.execute(new Runnable {
        def run() = cb(Right(()))
      })
    }
  }

I actually could see what's on master to be more efficient, albeit ugly to look at.

Just my 2 cents. I'm probably microoptimizing for nothing so a second perspective would be nice.

This comment has been minimized.

@rossabaker

rossabaker Dec 16, 2017

Member

That's one of the hotspots in a ping test, which sadly is how people choose libraries. (Shakes fist at naive reactions to Techempower.) Okay, let's be conservative there, but the sanctimonious logging could be the same.

@rossabaker

rossabaker Dec 16, 2017

Member

That's one of the hotspots in a ping test, which sadly is how people choose libraries. (Shakes fist at naive reactions to Techempower.) Okay, let's be conservative there, but the sanctimonious logging could be the same.

@jmcardon jmcardon added freezer and removed freezer labels Dec 15, 2017

jmcardon added some commits Dec 22, 2017

@rossabaker rossabaker changed the title from (WIP) remove try/catch semantics in otherwise pure code to Remove try/catch semantics in otherwise pure code Dec 22, 2017

rossabaker and others added some commits Dec 22, 2017

@rossabaker

This comment has been minimized.

Show comment
Hide comment
@rossabaker

rossabaker Dec 22, 2017

Member

For expediency, gambling that Travis likes this one since it liked the last one except for scalafmt.

Member

rossabaker commented Dec 22, 2017

For expediency, gambling that Travis likes this one since it liked the last one except for scalafmt.

@rossabaker rossabaker merged commit aff7a46 into http4s:master Dec 22, 2017

0 of 2 checks passed

continuous-integration/appveyor/pr Waiting for AppVeyor build to complete
Details
continuous-integration/travis-ci/pr The Travis CI build is in progress
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment