Skip to content
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

#73 Scala Native Curl based backend #105

Merged
merged 28 commits into from
Jul 20, 2018

Conversation

pcejrowski
Copy link
Contributor

@pcejrowski pcejrowski commented Jun 4, 2018

#73 This is Curl based backend for Scala Native.

@pcejrowski pcejrowski mentioned this pull request Jun 4, 2018
@pcejrowski pcejrowski changed the title WIP: Scala Native Curl based backend WIP: #73 Scala Native Curl based backend Jun 4, 2018
@adamw
Copy link
Member

adamw commented Jun 5, 2018

Looks really promising, thanks for your work!
I just removed the dependency on URLDecoder yesterday, this should be helpful here.

Do I understand correctly that no tests are runnable currently? If so, maybe instead of moving them, the native subproject could override the test sbt settings, remove the dependency on scalatest and switch off the tests (at least until scalatest-native is there)?

@pcejrowski
Copy link
Contributor Author

@adamw Thanks! There was one more dependency on URLDecoder left -- I'm removing it in #109 .
I will try following the tests' setup pattern from coreJS.

@pcejrowski pcejrowski force-pushed the native-backend branch 2 times, most recently from 6d0491d to 89a393e Compare June 6, 2018 19:55
@pcejrowski
Copy link
Contributor Author

I have started using Curl based encoder (89a393e) but I'm still having one test failing:

[info] - host www.mikołak.net should serialize to http://www.xn--mikoak-6db.net *** FAILED ***
[info]   "http://www.[miko%C5%82ak.ne]" was not equal to "http://www.[xn--mikoak-6db.net]" (UriTests.scala:104)
[info]   Analysis:
[info]   "http://www.[miko%C5%82ak.ne]" -> "http://www.[xn--mikoak-6db.net]"

but when I run curl -v 'www.mikołak.net' it also says: * IDN support not present, can't parse Unicode domains.
I'm green in those topics, so any help is welcome.

@adamw
Copy link
Member

adamw commented Jun 7, 2018

Ah see, curl is yet another backend which doesn't support IDN domains ;)

But I suppose if the IDN Java class is not available, there are only two possibilities: (1) copy its functionality into our codebase (2) live with the fact that - at least for now - IDN domains won't work :)

@pcejrowski
Copy link
Contributor Author

I have just added test of the backend, but because of the Native scalatest status: [error] (Nativetest / executeTests) The test program never connected to sbt. even though the response is read by Curl (visible in Curl's log), so we might get stuck here.
I'll try copying IDN.toASCII into Sttp's codebase to close the previous issue.

At this moment, the main feature left is request body support.

@guymers
Copy link
Contributor

guymers commented Jun 22, 2018

Would it be easier to use libidn instead of copying IDN.toASCII?

Maybe the test problem is caused by native ScalaTest not handling tests that return futures? Does uTest (only testing library that seems to have a released native version) have the same problem?

@pcejrowski
Copy link
Contributor Author

@guymers - I've just added IDN based on libidn. Thanks for the suggestion.

@pcejrowski
Copy link
Contributor Author

I have just added significant part of tests that I was able to transfer from shared HttpTest. I changed AsyncFreeSpec into FreeSpec and it works. All tests that are commented out are failing for now. I plan to work on them in the next days.
It still requires some clean up of test classes, since some of them are currently redundant.

@pcejrowski
Copy link
Contributor Author

I have just bumped Scala Native version to 3.8 and removed encoding based on Curl, since URLEncoder is added in SN3.8.

@densh Thanks for the explanation. I'll experiment around async tests.

@adamw
Copy link
Member

adamw commented Jul 18, 2018

@pcejrowski I wanted to convert the tests to a synchronous version, however this won't work with scala.js, as it's single-threaded and the only way to do something in parallel there is to work with Futures. So the tests need to be based on AsyncFreeSpec.

So if it turns out it's not possible to use AsyncFreeSpec with scala-native, let's just go with the copied tests approach. Better this than nothing :)

@pcejrowski
Copy link
Contributor Author

@adamw yeah, I have been playing around AsyncFreeSpec that explicitly waits for the block passed into def in(f: Future[Assertion]), but haven't got any progress.

@adamw
Copy link
Member

adamw commented Jul 19, 2018

@pcejrowski let me know how it goes - I can either merge the PR as is, or wait for the results of your trials :)

@@ -29,6 +29,13 @@ val commonJSSettings = Seq(
}
) ++ browserTestSettings

val commonNativeSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq(
organization := "com.softwaremill.sttp",
scalaVersion := "2.11.12",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So scala native is based on 2.11? What about 2.12?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no 2.12 support.
2.12 support is tracked here: scala-native/scala-native#233


import scala.concurrent.duration._

trait SyncHttpTest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this test stays as-is (copy-pasted), maybe you could add a comment explaining why it's copied and how to add how the tests cases differ from HttpTest

@pcejrowski
Copy link
Contributor Author

@adamw
I have just added the comment you requested, but I see no hope for some sort of AsyncFreeSpec to be ready soon.
If you are ok with that, please merge it as-is.

@adamw adamw merged commit 4726bdb into softwaremill:master Jul 20, 2018
@adamw
Copy link
Member

adamw commented Jul 20, 2018

@pcejrowski do you maybe know why I'm getting

[error] /Users/adamw/projects/sttp/core/native/target/scala-2.11/native/lib/optional/re2.cpp:61:10: fatal error: 're2/re2.h' file not found
[error] #include <re2/re2.h>

when trying to run the tests locally? (macos)

@adamw
Copy link
Member

adamw commented Jul 20, 2018

brew install re2 helped :)

@adamw
Copy link
Member

adamw commented Jul 20, 2018

@pcejrowski though now I've got another one :) I installed

$ brew install llvm
$ brew install bdw-gc re2 # optional

as specified on http://www.scala-native.org/en/latest/user/setup.html, but now I get:

[error] ld: library not found for -lidn
[error] clang: error: linker command failed with exit code 1 (use -v to see invocation)
[info] Linking native code (immix gc) (46 ms)
[info] Starting process '/Users/adamw/projects/sttp/core/native/target/scala-2.11/core-out' on port '63807'.
Exception in thread "Thread-488" java.io.IOException: Cannot run program "/Users/adamw/projects/sttp/core/native/target/scala-2.11/core-out": error=2, No such file or directory
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
	at scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:71)
	at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:102)
	at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$anonfun$runBuffered$1(ProcessBuilderImpl.scala:150)
	at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.java:12)
	at scala.sys.process.ProcessLogger$$anon$1.buffer(ProcessLogger.scala:99)
	at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.runBuffered(ProcessBuilderImpl.scala:150)
	at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$bang(ProcessBuilderImpl.scala:116)
	at scala.scalanative.testinterface.ComRunner$$anon$1.run(ComRunner.scala:31)
Caused by: java.io.IOException: error=2, No such file or directory
	at java.lang.UNIXProcess.forkAndExec(Native Method)
	at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
	at java.lang.ProcessImpl.start(ProcessImpl.java:134)
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
	... 8 more

Any pointers maybe where to look?

@densh
Copy link

densh commented Jul 20, 2018

@adamw

ld: library not found for -lidn

You need to install idn library using homebrew probably.

@pcejrowski
Copy link
Contributor Author

@adamw Congrats on your first contact with Scala Native :)

brew install libidn might help. It's interesting that it worked fine on Travis.

@pcejrowski pcejrowski deleted the native-backend branch July 20, 2018 16:23
@adamw
Copy link
Member

adamw commented Jul 20, 2018

@densh Thanks, trying :)
@pcejrowski I don't think the native version is built on travis: https://github.com/softwaremill/sttp/blob/master/.travis.yml#L22

@adamw
Copy link
Member

adamw commented Jul 20, 2018

@densh @pcejrowski new errors:

[error] Undefined symbols for architecture x86_64:
[error]   "_curl_mime_addpart", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimeHandleOps::addPart_ptr in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_data", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimePartHandleOps::withData_java.lang.String_i64_scala.scalanative.native.Zone_scala.Enumeration$Value in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_filename", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimePartHandleOps::withFileName_java.lang.String_scala.scalanative.native.Zone_scala.Enumeration$Value in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_headers", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimePartHandleOps::withHeaders_ptr_i32_scala.Enumeration$Value in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_init", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$CurlHandleOps::mime_ptr in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_name", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimePartHandleOps::withName_java.lang.String_scala.scalanative.native.Zone_scala.Enumeration$Value in com.softwaremill.sttp.curl.ll.o
[error]   "_curl_mime_type", referenced from:
[error]       _com.softwaremill.sttp.curl.CurlApi$MimePartHandleOps::withMimeType_java.lang.String_scala.scalanative.native.Zone_scala.Enumeration$Value in com.softwaremill.sttp.curl.ll.o
[error] ld: symbol(s) not found for architecture x86_64
[error] clang: error: linker command failed with exit code 1 (use -v to see invocation)

:)

@pcejrowski
Copy link
Contributor Author

I think you might have an old version of Curl. I have 7.60.0.

@pcejrowski
Copy link
Contributor Author

pcejrowski commented Jul 20, 2018

Curl is required in version 7.56.0+. I'm about to submit a PR with a note on that in docs.

#127

@adamw
Copy link
Member

adamw commented Jul 20, 2018

Ok, I've got curl 7.61.0, I've updated the PATH so that it's used, but I don't think sbt sees it, as it gives the same error. Anything special I need to set in sbt? Printing the env from within sbt gives the correct PATH.

@adamw
Copy link
Member

adamw commented Jul 20, 2018

The brew message says that:

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/curl/lib
    CPPFLAGS: -I/usr/local/opt/curl/include

so maybe I need to pass those flags to the compiler somehow?

@adamw
Copy link
Member

adamw commented Jul 20, 2018

nativeCompileOptions += "-I/usr/local/opt/curl/include",
    nativeLinkingOptions += "-L/usr/local/opt/curl/lib"

helped :)

@adamw
Copy link
Member

adamw commented Jul 20, 2018

@pcejrowski I've updated the SyncHttpTest and SyncHttpTestExtensions to include the same tests as in the "normal" versions. Some tests are failing - could you take a look?

I've also updated the README to include instructions on building with the scala-native backend.

@adamw
Copy link
Member

adamw commented Jul 20, 2018

Because the native backend setup is non-trivial, I've changed the default build not to include the native backend in the aggregate project by default. To include it, the STTP_NATIVE env variable must be defined. All is documented in the readme.

I'll be back on Tuesday :)

@pcejrowski
Copy link
Contributor Author

@adamw got them to work in #129
Enjoy the weekend!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants