Open tomtaylor opened 2 years ago
Okay, the first thing I can see is that the code (read: me) is wrapping to call to index data in an unnecessary Go routine:
https://github.com/whosonfirst/go-whosonfirst-spatial-www/blob/main/server/app.go#L122-L129
It is unnecessary because the code it is calling invokes its own Go routine:
So the code starts by saying: Spatial application, go an index these paths in the background.
And a little further down it says: Create a data (HTTP) handler using the spatial application's spatial database:
https://github.com/whosonfirst/go-whosonfirst-spatial-www/blob/main/server/app.go#L161
If you look carefully at the data handler you'll see it doesn't know anything about "spatial applications" but only about readers; specifically the spatial application implements the reader.Reader
interface:
https://github.com/whosonfirst/go-whosonfirst-spatial-rtree/blob/main/database.go#L589
That part is important. The data handler doesn't know anything about the spatial application or the spatial application's iterator which is indexing data in the background, notably the IsIndexing()
method:
So it's very possible for the data handler to start getting requests for records that haven't been indexed yet, for example with a really big repo like GB postalcodes.
One bad habit that I've been trying to address going forward is not wrapping other people's errors in something that will help track down errors. Not doing this often leads to getting an error that just says io.EOF
which while self-explanatory is often unhelpful. I mention that because both the (HTTP) data handler and the go-whosonfirst-spatial-rtree
implementation of the Reader interface suffer from this:
https://github.com/whosonfirst/go-whosonfirst-spatial-rtree/blob/main/database.go#L620-L646
At the end of all of this my immediate hunch is that the data race is being triggered by the nested Go routines and the io.EOF
error because... I'm not sure because it doesn't seem like the kind of error to be triggered even if a record hasn't been indexed.
So, I will create a new branch that does the following:
Hopefully one or both of those things will address the issues you're seeing.
Can you try the issue-22
branch and see if that helps.
https://github.com/whosonfirst/go-whosonfirst-spatial-www/compare/issue-22
For example:
$> go run -mod vendor cmd/server/main.go -spatial-database-uri rtree:// /usr/local/data/sfomuseum-data-whosonfirst/
%> curl -v http://localhost:8080/data/85632685
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /data/85632685 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 503 Service Unavailable
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Fri, 12 Aug 2022 18:19:02 GMT
< Content-Length: 30
<
Service unavailable: indexing
* Connection #0 to host localhost left intact
Note that the go-whosonfirst-spatial-pip/api
PIP handler was already checking whether indexing was happening:
I was trying to track down a bug where infrequently connections to the PIP endpoint would return
EOF
in my HTTP Client, so I booted the server up with-race
to see if this might be a server error. I don't think it is, but I did spot this in the logs as the server boots.