michaelruocco / embedded-mysql-plugin

gradle plugin for embedded mysql
17 stars 8 forks source link

mysql does not stop after calling stopEmbeddedMysql #7

Open LazyProphet opened 7 years ago

LazyProphet commented 7 years ago

If I start via startEmbeddedMysql I can connect as expected. Calling the start twice results in expected error, because the configured port is blocked. After calling stopEmbeddedMysql the process exits successfully, but I can still connect and the java process which started the mysql is still running. Please tell me, if and how I should provide more information.

Plugin version is 2.1.5 and output of gradle -v is

-----------------------------------------------------------
Gradle 3.5
------------------------------------------------------------

Build time:   2017-04-10 13:37:25 UTC
Revision:     b762622a185d59ce0cfc9cbc6ab5dd22469e18a6

Groovy:       2.4.10
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_131 (Oracle Corporation 25.131-b11)
OS:           Windows 10 10.0 amd64
michaelruocco commented 7 years ago

Sorry for the delayed response on this, I have been busy with work and not had a chance to take a look. I guess my first question would be why do you need to call startEmbeddedMysql twice if you are expecting it to fail?

Are you still unable to stop the process when you only attempt to start mysql once?

michaelruocco commented 7 years ago

Also, are you able to push any code or send me a reference to some code that demonstrates the issue you are seeing, I don't seem to be able to recreate it easily.

michaelruocco commented 7 years ago

@LazyProphet do you have any details you are able to share on this issue as I am having trouble trying to recreate the issue you described.

LazyProphet commented 7 years ago

not that much. gradle debug says:

22:22:55.287 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':ApplicationServer:stopEmbeddedMysql' is up-to-date
22:22:55.288 [INFO] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Executing task ':ApplicationServer:stopEmbeddedMysql' (up-to-date check took 0.0 secs) due to:
  Task has not declared any outputs.
22:22:55.288 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':ApplicationServer:stopEmbeddedMysql'.
22:22:55.288 [DEBUG] [org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter] Removed task artifact state for {} from context.
22:22:55.288 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':ApplicationServer:stopEmbeddedMysql'
22:22:55.288 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :ApplicationServer:stopEmbeddedMysql (Thread[Daemon worker Thread 5,5,main]) completed. Took 0.003 secs.
22:22:55.288 [DEBUG] [org.gradle.internal.operations.DefaultBuildOperationWorkerRegistry] Worker root.1 completed (0 in use)
22:22:55.289 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[Daemon worker Thread 5,5,main]] finished, busy: 0.003 secs, idle: 0.001 secs
22:22:55.289 [DEBUG] [org.gradle.execution.taskgraph.DefaultTaskGraphExecuter] Timing: Executing the DAG took 0.097 secs
22:22:55.289 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
22:22:55.289 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] BUILD SUCCESSFUL
22:22:55.289 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
22:22:55.290 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] Total time: 3.934 secs

in build.gradle

embeddedMysql {
    url = 'jdbc:mysql://localhost:3306/eformdb'
    username = 'user'
    password = ''
    version = 'v5_7_latest'
}

i have no clue why it doesn't stop. have to kill it manually.

michaelruocco commented 7 years ago

Hmm, I am wondering if it is due to the task showing as up-to-date. What happens if you try to add an outputs.upToDateWhen { false } to the stop embeddedMysqlTask in your build.gradle file?

E.g.

stopEmbeddedMysql.outputs.upToDateWhen { false }

If that doesn't help, are you able to push the code you are working on to a github repository so I can pull it down and take a look to try and help?

jakemonO commented 7 years ago

same problem. here's the relevebat part of my gradle file...

//testing tasks
embeddedMysql {
    url = "jdbc:mysql://${unittest_mysql_host}:${unittest_mysql_port}/${unittest_mysql_db}"
    username = unittest_mysql_username
    password = unittest_mysql_password
    version = unittest_mysql_version
}

stopEmbeddedMysql.outputs.upToDateWhen { false }

using unittest_mysql_version=v5_6_24. Any updates on this issue?

michaelruocco commented 7 years ago

Hi @jakemonO,

Are you able to push the changes to the project that recreates the issue? I have not been able to recreate the problem myself so am unable to look at a fix.

Thanks

jakemonO commented 7 years ago

Hmm. I'm referring to calling start and stop in subsequent gradle executions - it looks like if I call start and stop inside of a single gradle build/task it stops, though. Is that expected behavior?

michaelruocco commented 7 years ago

I have not tried it myself by running a start and then a stop as a completely separate execution, but you wouldn't have a handle on the database anymore so I wouldn't expect that to work.

All the use cases I have had so far have been start -> run some tests -> stop all within a single execution. I will see if I get time to try out your use case at some point but as I said I wouldn't expect that to work, I am also not sure whether it would be possible in the underlying library I am using, but I expect it might not be possible.

michaelruocco commented 6 years ago

Hi @jakemonO / @LazyProphet,

Apologies for the long delay in updating on this issue, I have just found the time to fix another issue that has been outstanding for a bit longer than this one. I believe I might have a potential idea around fixing this issue.

I am hopeful that I will have time to have a proper go at it over the next week or so, so I will keep you updated on progress.

ezraroi commented 6 years ago

Hi @michaelruocco , the issue is that you save the pid as project property (extraProperties). This is not saved between different executions. Example for such use case can be debugging tests... i want to start the mysql.. run some tests manually... and stop after it.

Maybe saving the pid in the file system can solve this

michaelruocco commented 6 years ago

I have looked into this a bit more, and it is not just the pid that is stored into the extra properties, it is the embeddedMysql object from the underlying library itself (https://github.com/wix/wix-embedded-mysql/blob/master/wix-embedded-mysql/src/main/java/com/wix/mysql/EmbeddedMysql.java) I don't see any methods that expose the pid unless I am missing something? If I could get hold of the PID then you are right that it could be persisted to the file system.

The bigger question for me would be why you need the code to automatically spin up the database if you are planning on running the tests manually? Could you not just start a mysql service manually too? If you are manually running tests I am not sure what the benefit of having mysql start automatically is. I had always assumed that the plugin would be used to support automated testing use cases.

michaelruocco commented 4 years ago

Hi @ezraroi, @jakemonO, @LazyProphet is this causing an issue / problem still or are you happy for this to be closed?

michaelruocco commented 4 years ago

I am closing this as I am unable to recreate the issue, if I run startEmbeddedMysql and don't call stop the process seems to be killed after the gradle task completes and the JVM stops anyway. If anyone can help me recreate the issue I will be happy to open again.

acusworth commented 4 years ago

I recently tried integrating this plugin to my project but am encountering the same issue. The stopEmbeddedMysql tasks isn't terminating the process despite an apparent successful run. Interestingly like you said calling startEmbeddedMysql does terminate the process but thats kinda a hacky way to deal with the issue.

I did a quick test to use it like gw startEmbeddedMysql test stopEmbeddedMysql and this starts and stops as expected. We were hoping to have something that would allow us to run the MySql locally so we can run our service against it and terminate when finished. The problem here is also that the mysql process doesn't stop if there's a test failure.

michaelruocco commented 4 years ago

Hi @acusworth, if the issue is just that MySQL is not being stopped for a failing test, could you just add some config so that’s the test task is finalised by stopEmbeddedMysql maybe? Do you have an example where the issue is re created so I can take a look at all?

acusworth commented 4 years ago

@michaelruocco That had crossed my mind, building in a direct dependency into our test tasks to include the DB. Thats would work well for purely automated tests but still doesn't solve our need to start a DB instance locally and quickly for the purposes of running our service for manual debugging. I can't share the exact project I'm working on but I recycled an old project of mine to have the same setup in terms of your plugin (and gradle version) https://github.com/acusworth/Java8Learning/blob/master/build.gradle

Based on previous comments I've read It looks like the PID of MySql isn't being persisted. Perhaps an alternative would be to look up the PID and kill it, checking if MySql is dead before the task finishes.

michaelruocco commented 4 years ago

Hi @acusworth, this morning I have updated a very old example project I had laying around to demonstrate how the plugin could be used for block local (manual) testing and automated testing, you can find it here:

https://github.com/michaelruocco/web-template

The two commands available (which I think map to the requirements you mentioned above) are:

./gradlew bootRun //this can be used for a local start up for manual testing / debugging
./gradlew cucumber //this will run a set of automated tests

Please take a look and see if it helps with any of the issues you are seeing? If not please let me know and I can take another look.

To be perfectly honest using the embeddedMysql is probably a little bit "old hat" now anyway. Hence why I don't do much maintenance on this repo anymore. I find a better approach is to use docker containers and docker compose for external dependencies like databases etc, there are some very nice gradle plugins that make this very easy:

I have a few examples of these in use too: https://github.com/michaelruocco/idv/blob/master/app/spring-app/build.gradle https://github.com/michaelruocco/idv/blob/master/services/verification-context/adapter/db/dynamo/build.gradle#L26

These are a bit more complex to get to grips with initially but are much more flexible and re-usable than using the embedded plugin, as you can use the same approach for anything that is built into a docker image, e.g. dynamoDb databases, mongoDatabases, redis, etc etc.

Hope some of that helps!

acusworth commented 4 years ago

@michaelruocco Ya I see the example you're providing. That pattern is good, not sure it will work with our application as we run Dropwizard instead of Spring but I'll try it out. We originally considered using minikube to set up dependencies and it works but its one of the more complex setups we were hoping to avoid by using this plugin. Thanks for your suggestions and assistance.

michaelruocco commented 4 years ago

It should work just as well with dropwizard, provided if you can run from gradle using a task as bootRun does. When I have used dropwizard in the past I have just achieved this by using the standard gradle application plugin and configuring it to run the main dropwizard class.

I had a hunt around and I actually had a dropwizard example that I forgot about that also used this plugin, the same sort of configuration is working there too: https://github.com/michaelruocco/dropwizard-web-template. That might prove helpful too?