Is there any way to close the database connection without terminating the HTTP server?
my code:
func thisone(w http.ResponseWriter,r *http.Request){
/*connect the db*/
defer database.Close()
/*query the database*/
}
func main(){
http.HandleFunc("/route",thisone)
http.ListenAndServe(":8000",nil)
}
what this does is after querying the database it terminates the program and stopped listening to the port
but I want to keep listening to the port even after the database connection is close.
so is there any way to do that
Thank You
Every time you are querying the database you are calling thisone() and every time that function is executed is closing the database connection. Try to put database.Close() inside main function.
func main(){
defer database.Close()
http.HandleFunc("/route",thisone)
http.ListenAndServe(":8000",nil)}
That's a little weird that you have an error putting up database.Close() in the main function because I recently made an API Rest with Go a little similar. You can see the code here.I hope it is useful.
Github API Rest with Go
Related
I have a Flex App written in Go and React that is deployed to Google App engine. I would like it to interact with a MySql Database (2nd generation) on Google Cloud over a Unix socket. I believe the issue lies with the Go server not launching/responding to requests (see below for justification). The App is located at https://haveibeenexploited.appspot.com/
The project is simple. I have two routes in my Server:
server.go
package main
import (
"net/http"
"searchcontract"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("./app/build")))
http.HandleFunc("/search", searchcontract.SearchContract)
http.ListenAndServe(":8080", nil)
}
The second route ("/search") is activated when a user hits the search button. Ideal behavior should return a row specifying the exploits available for the given "contract address" which React writes out to the screen.
searchcontract/searchcontract.go
//SearchContract is a handler that queries the DB for compromised contracts.
func SearchContract(w http.ResponseWriter, r *http.Request) {
var contractName contractID //Used for parsing in contractName
queryResult := getRow(&contractName.Name)
w.WriteHeader(200)
json.NewEncoder(w).Encode(queryResult)
}
//processRow queries the DB for a contract with ID value of name.
func getRow(contractName *string) *ContractVulnerabilityInfo {
var storage ContractVulnerabilityInfo //stores row to encode
//Login to database
...
scanErr := db.QueryRow("SELECT * FROM contracts WHERE ContractAddress=?;", &contractName).Scan(&storage.ContractAddress, &storage.IntegerOverflow, &storage.IntegerUnderflow, &storage.DOS, &storage.ExceptionState, &storage.ExternalCall, &storage.ExternalCallFixed, &storage.MultipleCalls, &storage.DelegateCall, &storage.PredictableEnv, &storage.TxOrigin, &storage.EtherWithdrawal, &storage.StateChange, &storage.UnprotectedSelfdestruct, &storage.UncheckedCall)
...
return &storage
}
My app.yaml file should allow me to deploy this flex app and does:
runtime: go1.12
env: flex
handlers:
- url: /.*
script: _server # my server.go file handles all endpoints
automatic_scaling:
max_num_instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
env_variables:
# user:password#unix(/cloudsql/INSTANCE_CONNECTION_NAME)/dbname
MYSQL_CONNECTION: root:root#unix(/cloudsql/haveibeenexploited:us-west1:hibe)/mythril
# https://cloud.google.com/sql/docs/mysql/connect-app-engine
beta_settings:
cloud_sql_instances: haveibeenexploited:us-west1:hibe
I am able to query the database successfully on localhost.Localhost correctly shows address
However, whenever I try to implement and push to AppEngine, when I query something that should be in the database, it does not show up in the remote App! App Engine does not show address in database. Furthermore, I get a status code of '0' returned, which indicates to me that the server function isn't even being called at all ('200' is what I expect if successful or some other error message.').
Summary
I can't wrap my head around this bug. What should work locally should work remotely. Also, I can't debug this app probably because Stackdriver does not support flex apps and the devserver Google Cloud provides does not support Go Apps.
I believe the primary issue is with Go not speaking to the React element correctly or the routing not being taken care of appropriately.
1) The problem does not lie with MySql connection/database access
- I changed my route to only be one page, turned off React, and included a hardcoded query. The result on localhost. The result on App Engine
2) There is an issue in either a) my routing or b) the interaction between React and Go.
3) Go seems to start correctly... at least when React is not started.
Any help is appreciated.
EDIT I believe that the go app indeed is still running, but the searchfunction is failing for whatever reason. The reason I believe this is because when I add another route for haveibeenexploited.com/hello, it works.
I have a Sparkjava app which I have deployed on a Tomcat server. It uses SQL2O to interface with the MySQL-database. After some time I start to have trouble connecting to the database. I've tried connecting directly from SQL2O, connecting through HikariCP and connecting through JNDI. They all work for about a day, before I start getting Communications link failure. This app gets hit a handful of times a day at best, so performance is a complete non issue. I want to configure the app to use one database connection per request. How do I go about that?
The app doesn't come online again afterwards until I redeploy it (overwrite ROOT.war again). Restarting tomcat or the entire server does nothing.
Currently every request creates a new Sql2o object and executes the query using withConnection. I'd be highly surprised if I was leaking any connections.
Here's some example code (simplified).
public class UserRepositry {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
protected Sql2o sql2o = new Sql2o("jdbc:mysql://mysql.server.name/dbname?serverTimezone=UTC", "username", "password");
public List<Users> getUsers() {
return sql2o.withConnection((c, o) -> {
return c.createQuery(
"SELECT\n" +
" id,\n" +
" name\n" +
"FROM users"
)
.executeAndFetch(User.class);
});
}
}
public class Main {
public static void main(String[] args) {
val gson = new Gson();
port(8080);
get("/users", (req, res) -> {
return new UserRepository().getUsers();
}, gson::toJson);
}
}
If you rely on Tomcat to provide the connection to you: It's coming from a pool. Just go with plain old JDBC and open that connection yourself (and make sure to close it as well) if you don't like that.
So much for the answer to your question, to the letter. Now for the spirit: There's nothing wrong with connections coming from a pool. In all cases, it's your responsibility to handle it properly: Get access to a connection and free it up (close) when you're done with it. It doesn't make a difference if the connection is coming from a pool or has been created manually.
As you say performance is not an issue: Note that the creation of a connection may take some time, so even if the computer is largely idle, creating a new connection per request may have a notable effect on the performance. Your server won't overheat, but it might add a second or two to the request turnaround time.
Check configurations for your pool - e.g. validationQuery (to detect communication failures) or limits for use per connection. And make sure that you don't run into those issues because of bugs in your code. You'll need to handle communication errors anyways. And, again, that handling doesn't differ whether you use pools or not.
Edit: And finally: Are you extra extra sure that there indeed is no communication link failure? Like: Database or router unplugged every night to connect the vacuum cleaner? (no pun intended), Firewall dropping/resetting connections etc?
I have a question regarding the flow of go lang code.
In my main function, I am opening mysql connection and then using `defer" to close the connection at the end of the connection.
I have route where WebSocket is set up and used.
My Question is will program open connection every time, WebSocket is used to send and receive a message or will it just open once the page was loaded.
Here is how my code looks like:-
package main
import (
// Loading various package
)
func main() {
// Opening DB connection -> *sql.DB
db := openMySql()
// Closing DB connection
defer db.Close()
// Route for "websocket" end point
app.Get("/ws", wsHandler(db))
// Another route using "WebSocket" endpoint.
app.Get("/message", message(db))
}
Now, while a user is at "message" route, whenever he is sending the message to other users, Will mysql - open and close connection event will happen every time, when the message is being sent and receive using "/ws" route?
Or will it happen Just once? whenever "/message" route and "/ws" event is called the first time.
My Purpose of using "db" in "wsHandler" function is to verify and check if the user has permission to send a message to the particular room or not.
But there is no point opening and closing connection every second while WebSocket emits message or typing event.
What would be the best way to handle permission checking in "/ws" route, if above code is horror? Considering a fact there will be few hundred thousand concurrent users.
Assuming db is *sql.DB your code seems fine, I'm also assuming that your example is incomplete and your main does not actually return right away.
The docs on Open state:
The returned DB is safe for concurrent use by multiple goroutines and
maintains its own pool of idle connections. Thus, the Open function
should be called just once. It is rarely necessary to close a DB.
So wsHandler and message should be ok to use it as they please as long as they don't close DB themselves.
In using the erlang mysql module the exposed external functions are:
%% External exports
-export([start_link/5,
start_link/6,
start_link/7,
start_link/8,
start/5,
start/6,
start/7,
start/8,
connect/7,
connect/8,
connect/9,
fetch/1,
fetch/2,
fetch/3,
prepare/2,
execute/1,
execute/2,
execute/3,
execute/4,
unprepare/1,
get_prepared/1,
get_prepared/2,
transaction/2,
transaction/3,
get_result_field_info/1,
get_result_rows/1,
get_result_affected_rows/1,
get_result_reason/1,
encode/1,
encode/2,
asciz_binary/2
]).
From the this this, it is not apparent how to close a connection.
How a connection closed?
I quickly browsed through the mysql_driver code. You're right - it doesn't seem to have a mechanism to close opened connections. In fact I actually don't even see proper clean-up code to close the open sockets when a gen_server let's say gets shutdown (in the terminate method).
{Type, Result} = mysql:start_link(P1, Host, User, Passwd, DB),
stop(Result) closes the connection
I have a Delphi application which hits a database (usually MySql) every 60 seconds through a TTimer. The application is more or less an unattended bulletin board. If the network drops the application needs to continue running and connect back to the database when the connection is back. Often it might be over broadband, so chances are the connection is not always the best.
I am using the TAdoConnection component. This is opened at application startup and remains open. Whenever I need to make a new query I set the Connection to the open TAdoConnection. But I am finding this is not very reliable if there is a network drop.
What is the best way to connect to the database in this instance?
I have seen ways where you can build the connection string directly into the TAdoQuery. Would this be the proper way? Or is this excessively resource intensive? Sometimes I need to open 5-10 queries to get all the information.
Or how about doing this in the TTimer.OnTimer event:
Create TAdoConnection
Do All Queries
Free TAdoConnection
Thanks.
You should use single TAdoConnection object to avoid setting connection string to each component. Keep your connection object closed and open it when you need to access data. Something like this:
procedure OnTimer;
begin
MyAdoConnection.Open;
try
// Data access code here
...
finally
MyAdoConnection.Close;
end;
end;
You can additionally put another try/except block around MyAdoConnection.Open to catch situation where network is not available.
About second part of your question, best would be to put all your data access components in data module that you will create when you need to run data access procedures. Then you can put all your data access code in that data module and separate it from rest of the code.
You could try to open connection in OnCreate event of datamodule, but be careful to handle possible exceptions when opening connection. Close connection in OnDestroy event. Then you can use that datamodule like this:
procedure OnTimer;
var myDataModule : TMyDataModule;
begin
myDataModule := TMyDataModule.Create;
try
// Data access code here
myDataModule.DoSomeDatabaseWork;
finally
myDataModule.Free;
end;
end;