public static async Task <GeoLocation> FindOrUpdateInDatabase(double latitude, double longitude) { using (await DB_LOCK.LockAsync().ConfigureAwait(false)) { if (!Directory.Exists(CACHE_DIR)) { Directory.CreateDirectory(CACHE_DIR); } LiteEngine.Upgrade(DB_NAME, null, true); using (var db = new LiteDatabase(DB_NAME)) { db.GetCollection <GeoLocation>("locations").EnsureIndex(s => s.Id); var locationsCollection = db.GetCollection <GeoLocation>("locations"); var id = GetIdTokenFromLatLng(latitude, longitude); var geoLocation = locationsCollection.FindOne(x => x.Id == id); if (geoLocation != null) { return(geoLocation); } geoLocation = new GeoLocation(latitude, longitude); for (var i = 0; i < GEOCODING_MAX_RETRIES; i++) { try { await geoLocation.ReverseGeocode().ConfigureAwait(false); break; } catch (Exception) { if (i == GEOCODING_MAX_RETRIES - 1) { return(null); } // Just ignore exception and retry after delay await Task.Delay(i * 100).ConfigureAwait(false); } } // Before we store it to the database, ensure it must at least have country field set. if (string.IsNullOrEmpty(geoLocation.Country)) { return(null); } locationsCollection.Insert(geoLocation); return(geoLocation); } } }
public static async Task <GeoLocation> FindOrUpdateInDatabase(double latitude, double longitude) { if (BlacklistTimestamp > DateTime.UtcNow.ToUnixTime()) { return(null); } using (var db = new GeoLocationConfigContext()) { latitude = Math.Round(latitude, GEOLOCATION_PRECISION); longitude = Math.Round(longitude, GEOLOCATION_PRECISION); var geoLocation = db.GeoLocation.Where(x => x.Latitude == latitude && x.Longitude == longitude).FirstOrDefault(); if (geoLocation != null) { return(geoLocation); } geoLocation = new GeoLocation(latitude, longitude); for (var i = 0; i < GEOCODING_MAX_RETRIES; i++) { try { await geoLocation.ReverseGeocode().ConfigureAwait(false); break; } catch (GoogleGeocodingException e) { if (e.Status == GoogleStatus.OverQueryLimit) { BlackList(); return(null); } // Just ignore exception and retry after delay await Task.Delay(i * 100).ConfigureAwait(false); } catch (Exception) { if (i == GEOCODING_MAX_RETRIES - 1) { BlackList(); return(null); } // Just ignore exception and retry after delay await Task.Delay(i * 100).ConfigureAwait(false); } } // Before we store it to the database, ensure it must at least have country field set. if (string.IsNullOrEmpty(geoLocation.Country)) { return(null); } db.GeoLocation.Add(geoLocation); await db.SaveChangesAsync().ConfigureAwait(false); return(geoLocation); } }