mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
Implements task oriented ThreadService
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||||
|
*
|
||||||
|
* l2jserver2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* l2jserver2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.l2jserver.service.core.threading;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
* @param <T>
|
||||||
|
* the task return type
|
||||||
|
*/
|
||||||
|
public abstract class AbstractTask<T> implements Task<T> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||||
|
*
|
||||||
|
* l2jserver2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* l2jserver2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.l2jserver.service.core.threading;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
* @param <T>
|
||||||
|
* the task return type
|
||||||
|
*/
|
||||||
|
public interface Task<T> extends Callable<T> {
|
||||||
|
}
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jserver.service.core.threading;
|
package com.l2jserver.service.core.threading;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,18 +30,18 @@ public interface ThreadPool {
|
|||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* the task return type
|
* the task return type
|
||||||
* @param callable
|
* @param task
|
||||||
* the callable instance
|
* the callable instance
|
||||||
* @return the {@link AsyncFuture} notified once the task has completed
|
* @return the {@link AsyncFuture} notified once the task has completed
|
||||||
*/
|
*/
|
||||||
<T> AsyncFuture<T> async(Callable<T> callable);
|
<T> AsyncFuture<T> async(Task<T> task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an asynchronous tasks at an scheduled time.
|
* Executes an asynchronous tasks at an scheduled time.
|
||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* the task return type
|
* the task return type
|
||||||
* @param callable
|
* @param task
|
||||||
* the callable instance
|
* the callable instance
|
||||||
* @param delay
|
* @param delay
|
||||||
* the initial delay to wait before the task is executed
|
* the initial delay to wait before the task is executed
|
||||||
@@ -50,7 +49,7 @@ public interface ThreadPool {
|
|||||||
* the time unit of delay
|
* the time unit of delay
|
||||||
* @return the {@link AsyncFuture} notified once the task has completed
|
* @return the {@link AsyncFuture} notified once the task has completed
|
||||||
*/
|
*/
|
||||||
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Callable<T> callable);
|
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Task<T> task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an asynchronous tasks at an scheduled time.
|
* Executes an asynchronous tasks at an scheduled time.
|
||||||
@@ -73,5 +72,4 @@ public interface ThreadPool {
|
|||||||
* execute tasks.
|
* execute tasks.
|
||||||
*/
|
*/
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jserver.service.core.threading;
|
package com.l2jserver.service.core.threading;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.l2jserver.service.Service;
|
import com.l2jserver.service.Service;
|
||||||
@@ -39,7 +38,7 @@ public interface ThreadService extends Service {
|
|||||||
* the callable instance
|
* the callable instance
|
||||||
* @return the {@link AsyncFuture} notified once the task has completed
|
* @return the {@link AsyncFuture} notified once the task has completed
|
||||||
*/
|
*/
|
||||||
<T> AsyncFuture<T> async(Callable<T> callable);
|
<T> AsyncFuture<T> async(Task<T> callable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
||||||
@@ -58,7 +57,7 @@ public interface ThreadService extends Service {
|
|||||||
* the time unit of delay
|
* the time unit of delay
|
||||||
* @return the {@link AsyncFuture} notified once the task has completed
|
* @return the {@link AsyncFuture} notified once the task has completed
|
||||||
*/
|
*/
|
||||||
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Callable<T> callable);
|
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Task<T> callable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.l2jserver.service.core.threading;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.Delayed;
|
import java.util.concurrent.Delayed;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@@ -79,7 +78,7 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncFuture<T> async(Callable<T> callable) {
|
public <T> AsyncFuture<T> async(Task<T> callable) {
|
||||||
Preconditions.checkNotNull(callable, "callable");
|
Preconditions.checkNotNull(callable, "callable");
|
||||||
|
|
||||||
log.debug("Scheduling async task: {}", callable);
|
log.debug("Scheduling async task: {}", callable);
|
||||||
@@ -87,8 +86,7 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncFuture<T> async(long delay, TimeUnit unit,
|
public <T> AsyncFuture<T> async(long delay, TimeUnit unit, Task<T> callable) {
|
||||||
Callable<T> callable) {
|
|
||||||
Preconditions.checkArgument(delay >= 0, "delay < 0");
|
Preconditions.checkArgument(delay >= 0, "delay < 0");
|
||||||
Preconditions.checkNotNull(unit, "unit");
|
Preconditions.checkNotNull(unit, "unit");
|
||||||
Preconditions.checkNotNull(callable, "callable");
|
Preconditions.checkNotNull(callable, "callable");
|
||||||
@@ -352,14 +350,14 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncFuture<T> async(Callable<T> callable) {
|
public <T> AsyncFuture<T> async(Task<T> callable) {
|
||||||
log.debug("Task {} submited to {}", callable, name);
|
log.debug("Task {} submited to {}", callable, name);
|
||||||
return new AsyncFutureImpl<T>(executor.submit(callable));
|
return new AsyncFutureImpl<T>(executor.submit(callable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncFuture<T> async(long delay, TimeUnit unit,
|
public <T> AsyncFuture<T> async(long delay, TimeUnit unit,
|
||||||
Callable<T> callable) {
|
Task<T> callable) {
|
||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
log.debug("Task {} scheduled in {} {} to {}", new Object[] {
|
log.debug("Task {} scheduled in {} {} to {}", new Object[] {
|
||||||
callable, delay, unit, name });
|
callable, delay, unit, name });
|
||||||
@@ -371,8 +369,9 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
|||||||
public ScheduledAsyncFuture async(long delay, TimeUnit unit,
|
public ScheduledAsyncFuture async(long delay, TimeUnit unit,
|
||||||
long repeat, Runnable task) {
|
long repeat, Runnable task) {
|
||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
log.debug("Task {} scheduled every {} {} to {}", new Object[] {
|
log.debug(
|
||||||
task, repeat, unit, name });
|
"Task {} scheduled every {} {} to {}, starting in {}",
|
||||||
|
new Object[] { task, repeat, unit, name, delay });
|
||||||
return new ScheduledAsyncFutureImpl(executor.scheduleAtFixedRate(
|
return new ScheduledAsyncFutureImpl(executor.scheduleAtFixedRate(
|
||||||
task, delay, repeat, unit));
|
task, delay, repeat, unit));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,14 @@
|
|||||||
package com.l2jserver.service.database;
|
package com.l2jserver.service.database;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.l2jserver.model.Model;
|
import com.l2jserver.model.Model;
|
||||||
import com.l2jserver.model.id.ID;
|
import com.l2jserver.model.id.ID;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
|
import com.l2jserver.service.database.DatabaseService.TransactionExecutor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract DAO implementations. Store an instance of {@link DatabaseService}.
|
* Abstract DAO implementations. Store an instance of {@link DatabaseService}.
|
||||||
@@ -61,7 +62,7 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncFuture<T> selectAsync(final I id) {
|
public AsyncFuture<T> selectAsync(final I id) {
|
||||||
return threadService.async(new Callable<T>() {
|
return threadService.async(new AbstractTask<T>() {
|
||||||
@Override
|
@Override
|
||||||
public T call() throws Exception {
|
public T call() throws Exception {
|
||||||
return select(id);
|
return select(id);
|
||||||
@@ -92,18 +93,23 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final int saveObjects(T... objects) {
|
public final int saveObjects(final T... objects) {
|
||||||
int rows = 0;
|
return database.transaction(new TransactionExecutor() {
|
||||||
for (final T object : objects) {
|
@Override
|
||||||
rows += save(object);
|
public int perform() {
|
||||||
}
|
int rows = 0;
|
||||||
return rows;
|
for (final T object : objects) {
|
||||||
|
rows += save(object);
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final AsyncFuture<Integer> saveObjectsAsync(final T... objects) {
|
public final AsyncFuture<Integer> saveObjectsAsync(final T... objects) {
|
||||||
return threadService.async(new Callable<Integer>() {
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
return saveObjects(objects);
|
return saveObjects(objects);
|
||||||
@@ -119,7 +125,7 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
|||||||
@Override
|
@Override
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final AsyncFuture<Integer> insertObjectsAsync(final T... objects) {
|
public final AsyncFuture<Integer> insertObjectsAsync(final T... objects) {
|
||||||
return threadService.async(new Callable<Integer>() {
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
return insertObjects(objects);
|
return insertObjects(objects);
|
||||||
@@ -135,7 +141,7 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
|||||||
@Override
|
@Override
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final AsyncFuture<Integer> updateObjectsAsync(final T... objects) {
|
public final AsyncFuture<Integer> updateObjectsAsync(final T... objects) {
|
||||||
return threadService.async(new Callable<Integer>() {
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
return updateObjects(objects);
|
return updateObjects(objects);
|
||||||
@@ -151,7 +157,7 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
|||||||
@Override
|
@Override
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final AsyncFuture<Integer> deleteObjectsAsync(final T... objects) {
|
public final AsyncFuture<Integer> deleteObjectsAsync(final T... objects) {
|
||||||
return threadService.async(new Callable<Integer>() {
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer call() throws Exception {
|
public Integer call() throws Exception {
|
||||||
return deleteObjects(objects);
|
return deleteObjects(objects);
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ import com.l2jserver.service.cache.CacheService;
|
|||||||
import com.l2jserver.service.configuration.ConfigurationService;
|
import com.l2jserver.service.configuration.ConfigurationService;
|
||||||
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertyKey;
|
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertyKey;
|
||||||
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
|
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
import com.l2jserver.util.ArrayIterator;
|
import com.l2jserver.util.ArrayIterator;
|
||||||
@@ -129,6 +131,11 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
|
|||||||
*/
|
*/
|
||||||
private ScheduledAsyncFuture autoSaveFuture;
|
private ScheduledAsyncFuture autoSaveFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection used inside a transaction from multiple DAOs.
|
||||||
|
*/
|
||||||
|
private ThreadLocal<Connection> transactionalConnection = new ThreadLocal<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration interface for {@link AbstractJDBCDatabaseService}.
|
* Configuration interface for {@link AbstractJDBCDatabaseService}.
|
||||||
*
|
*
|
||||||
@@ -325,6 +332,46 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int transaction(TransactionExecutor executor) {
|
||||||
|
Preconditions.checkNotNull(executor, "executor");
|
||||||
|
try {
|
||||||
|
final Connection conn = dataSource.getConnection();
|
||||||
|
log.debug("Executing transaction {} with {}", executor, conn);
|
||||||
|
try {
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
transactionalConnection.set(conn);
|
||||||
|
final int rows = executor.perform();
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
return rows;
|
||||||
|
} catch (Exception e) {
|
||||||
|
conn.rollback();
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
transactionalConnection.remove();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
} catch (DatabaseException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new DatabaseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AsyncFuture<Integer> transactionAsync(
|
||||||
|
final TransactionExecutor executor) {
|
||||||
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
return transaction(executor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an <tt>query</tt> in the database.
|
* Executes an <tt>query</tt> in the database.
|
||||||
*
|
*
|
||||||
@@ -333,23 +380,47 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
|
|||||||
* @param query
|
* @param query
|
||||||
* the query
|
* the query
|
||||||
* @return an instance of <tt>T</tt>
|
* @return an instance of <tt>T</tt>
|
||||||
|
* @throws DatabaseException
|
||||||
|
* if any exception occur (can have nested {@link SQLException})
|
||||||
*/
|
*/
|
||||||
public <T> T query(Query<T> query) {
|
public <T> T query(Query<T> query) throws DatabaseException {
|
||||||
Preconditions.checkNotNull(query, "query");
|
Preconditions.checkNotNull(query, "query");
|
||||||
try {
|
try {
|
||||||
final Connection conn = dataSource.getConnection();
|
boolean inTransaction = false;
|
||||||
|
Connection conn = transactionalConnection.get();
|
||||||
|
if (conn == null) {
|
||||||
|
log.debug(
|
||||||
|
"Transactional connection for {} is not set, creating new connection",
|
||||||
|
query);
|
||||||
|
inTransaction = false;
|
||||||
|
conn = dataSource.getConnection();
|
||||||
|
}
|
||||||
log.debug("Executing query {} with {}", query, conn);
|
log.debug("Executing query {} with {}", query, conn);
|
||||||
try {
|
try {
|
||||||
return query.query(conn);
|
if (!inTransaction) {
|
||||||
} catch (SQLException e) {
|
conn.setAutoCommit(false);
|
||||||
log.error("Error executing query", e);
|
}
|
||||||
return null;
|
try {
|
||||||
|
return query.query(conn);
|
||||||
|
} finally {
|
||||||
|
if (!inTransaction) {
|
||||||
|
conn.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (!inTransaction) {
|
||||||
|
conn.rollback();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
conn.close();
|
if (!inTransaction) {
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (Throwable e) {
|
||||||
log.error("Could not open database connection", e);
|
log.error("Could not open database connection", e);
|
||||||
return null;
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,64 +571,52 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
|
|||||||
Preconditions.checkNotNull(conn, "conn");
|
Preconditions.checkNotNull(conn, "conn");
|
||||||
|
|
||||||
log.debug("Starting INSERT/UPDATE query execution");
|
log.debug("Starting INSERT/UPDATE query execution");
|
||||||
|
final String queryString = query();
|
||||||
|
|
||||||
|
log.debug("Preparing statement for {}", queryString);
|
||||||
|
final PreparedStatement st = conn.prepareStatement(queryString,
|
||||||
|
Statement.RETURN_GENERATED_KEYS);
|
||||||
try {
|
try {
|
||||||
conn.setAutoCommit(false);
|
int rows = 0;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final T object = iterator.next();
|
||||||
|
|
||||||
final String queryString = query();
|
log.debug("Parametizing statement {} with {}", st, object);
|
||||||
|
this.parametize(st, object);
|
||||||
|
|
||||||
log.debug("Preparing statement for {}", queryString);
|
log.debug("Sending query to database for {}", object);
|
||||||
final PreparedStatement st = conn.prepareStatement(queryString,
|
rows += st.executeUpdate();
|
||||||
Statement.RETURN_GENERATED_KEYS);
|
log.debug("Query inserted or updated {} rows for {}", rows,
|
||||||
try {
|
object);
|
||||||
int rows = 0;
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
final T object = iterator.next();
|
|
||||||
|
|
||||||
log.debug("Parametizing statement {} with {}", st,
|
// update object desire --it has been realized
|
||||||
object);
|
if (object instanceof Model && rows > 0) {
|
||||||
this.parametize(st, object);
|
log.debug("Updating Model ObjectDesire to NONE");
|
||||||
|
((Model<?>) object).setObjectDesire(ObjectDesire.NONE);
|
||||||
|
|
||||||
log.debug("Sending query to database for {}", object);
|
final Mapper<? extends ID<?>> mapper = keyMapper();
|
||||||
rows += st.executeUpdate();
|
if (mapper == null)
|
||||||
log.debug("Query inserted or updated {} rows for {}",
|
continue;
|
||||||
rows, object);
|
final ResultSet rs = st.getGeneratedKeys();
|
||||||
|
try {
|
||||||
// update object desire --it has been realized
|
log.debug(
|
||||||
if (object instanceof Model && rows > 0) {
|
"Mapping generated keys with {} using {}",
|
||||||
log.debug("Updating Model ObjectDesire to NONE");
|
mapper, rs);
|
||||||
((Model<?>) object)
|
while (rs.next()) {
|
||||||
.setObjectDesire(ObjectDesire.NONE);
|
final ID<?> generatedID = mapper.map(rs);
|
||||||
|
log.debug("Generated ID for {} is {}", object,
|
||||||
final Mapper<? extends ID<?>> mapper = keyMapper();
|
generatedID);
|
||||||
if (mapper == null)
|
((Model<ID<?>>) object).setID(generatedID);
|
||||||
continue;
|
mapper.map(rs);
|
||||||
final ResultSet rs = st.getGeneratedKeys();
|
|
||||||
try {
|
|
||||||
log.debug(
|
|
||||||
"Mapping generated keys with {} using {}",
|
|
||||||
mapper, rs);
|
|
||||||
while (rs.next()) {
|
|
||||||
final ID<?> generatedID = mapper.map(rs);
|
|
||||||
log.debug("Generated ID for {} is {}",
|
|
||||||
object, generatedID);
|
|
||||||
((Model<ID<?>>) object).setID(generatedID);
|
|
||||||
mapper.map(rs);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
rs.close();
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
rs.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.commit();
|
|
||||||
return rows;
|
|
||||||
} finally {
|
|
||||||
st.close();
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
return rows;
|
||||||
conn.rollback();
|
|
||||||
throw e;
|
|
||||||
} finally {
|
} finally {
|
||||||
conn.setAutoCommit(true);
|
st.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,43 +709,32 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService
|
|||||||
Preconditions.checkNotNull(conn, "conn");
|
Preconditions.checkNotNull(conn, "conn");
|
||||||
|
|
||||||
log.debug("Starting DELETE query execution");
|
log.debug("Starting DELETE query execution");
|
||||||
|
final String queryString = query();
|
||||||
|
|
||||||
|
log.debug("Preparing statement for {}", queryString);
|
||||||
|
final PreparedStatement st = conn.prepareStatement(queryString);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conn.setAutoCommit(false);
|
int rows = 0;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final T object = iterator.next();
|
||||||
|
|
||||||
final String queryString = query();
|
log.debug("Parametizing statement {} with {}", st, object);
|
||||||
|
this.parametize(st, object);
|
||||||
|
|
||||||
log.debug("Preparing statement for {}", queryString);
|
log.debug("Sending query to database for {}", object);
|
||||||
final PreparedStatement st = conn.prepareStatement(queryString);
|
rows = st.executeUpdate();
|
||||||
|
log.debug("Query deleted {} rows for {}", rows, object);
|
||||||
|
|
||||||
try {
|
dispose(object);
|
||||||
int rows = 0;
|
if (object instanceof Model) {
|
||||||
while (iterator.hasNext()) {
|
database.removeCache(((Model<?>) object)
|
||||||
final T object = iterator.next();
|
.getObjectDesire());
|
||||||
|
|
||||||
log.debug("Parametizing statement {} with {}", st,
|
|
||||||
object);
|
|
||||||
this.parametize(st, object);
|
|
||||||
|
|
||||||
log.debug("Sending query to database for {}", object);
|
|
||||||
rows = st.executeUpdate();
|
|
||||||
log.debug("Query deleted {} rows for {}", rows, object);
|
|
||||||
|
|
||||||
dispose(object);
|
|
||||||
if (object instanceof Model) {
|
|
||||||
database.removeCache(((Model<?>) object)
|
|
||||||
.getObjectDesire());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
conn.commit();
|
|
||||||
return rows;
|
|
||||||
} finally {
|
|
||||||
st.close();
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
return rows;
|
||||||
conn.rollback();
|
|
||||||
throw e;
|
|
||||||
} finally {
|
} finally {
|
||||||
conn.setAutoCommit(true);
|
st.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import com.l2jserver.service.cache.CacheService;
|
|||||||
import com.l2jserver.service.configuration.ConfigurationService;
|
import com.l2jserver.service.configuration.ConfigurationService;
|
||||||
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertyKey;
|
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationPropertyKey;
|
||||||
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
|
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
import com.l2jserver.util.ArrayIterator;
|
import com.l2jserver.util.ArrayIterator;
|
||||||
@@ -221,6 +223,22 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int transaction(TransactionExecutor executor) {
|
||||||
|
return executor.perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AsyncFuture<Integer> transactionAsync(
|
||||||
|
final TransactionExecutor executor) {
|
||||||
|
return threadService.async(new AbstractTask<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
return transaction(executor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an <tt>query</tt> in the database.
|
* Executes an <tt>query</tt> in the database.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -89,13 +89,8 @@ public interface DataAccessObject<O extends Model<?>, I extends ID<?>> extends
|
|||||||
int save(O object);
|
int save(O object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save several instances to the database. This method will only save if the
|
* Save several instances to the database using a transaction (if possible).
|
||||||
* object has changed.
|
* This method will only save if the object has changed.
|
||||||
* <p>
|
|
||||||
* Note that differently from {@link #insertObjects(Model...)},
|
|
||||||
* {@link #updateObjects(Model...)} and {@link #deleteObjects(Model...)},
|
|
||||||
* this method does not uses an transaction and could have a bigger
|
|
||||||
* performance hit.
|
|
||||||
*
|
*
|
||||||
* @param objects
|
* @param objects
|
||||||
* the objects
|
* the objects
|
||||||
@@ -104,13 +99,8 @@ public interface DataAccessObject<O extends Model<?>, I extends ID<?>> extends
|
|||||||
int saveObjects(@SuppressWarnings("unchecked") O... objects);
|
int saveObjects(@SuppressWarnings("unchecked") O... objects);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously save several instances to the database. This method will
|
* Asynchronously save several instances to the database using a transaction
|
||||||
* only save if the object has changed.
|
* (if possible). This method will only save if the object has changed.
|
||||||
* <p>
|
|
||||||
* Note that differently from {@link #insertObjects(Model...)},
|
|
||||||
* {@link #updateObjects(Model...)} and {@link #deleteObjects(Model...)},
|
|
||||||
* this method does not uses an transaction and could have a bigger
|
|
||||||
* performance hit.
|
|
||||||
*
|
*
|
||||||
* @param objects
|
* @param objects
|
||||||
* the objects
|
* the objects
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||||
|
*
|
||||||
|
* l2jserver2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* l2jserver2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.l2jserver.service.database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
public class DatabaseException extends RuntimeException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public DatabaseException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message
|
||||||
|
* the message
|
||||||
|
* @param cause
|
||||||
|
* the root cause
|
||||||
|
*/
|
||||||
|
public DatabaseException(String message, Throwable cause) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message
|
||||||
|
* the message
|
||||||
|
*/
|
||||||
|
public DatabaseException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cause
|
||||||
|
* the root cause
|
||||||
|
*/
|
||||||
|
public DatabaseException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import com.l2jserver.service.Service;
|
|||||||
import com.l2jserver.service.ServiceConfiguration;
|
import com.l2jserver.service.ServiceConfiguration;
|
||||||
import com.l2jserver.service.configuration.Configuration;
|
import com.l2jserver.service.configuration.Configuration;
|
||||||
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
|
import com.l2jserver.service.configuration.ProxyConfigurationService.ConfigurationName;
|
||||||
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service provides access to an database implementation. Each
|
* This service provides access to an database implementation. Each
|
||||||
@@ -46,4 +47,57 @@ public interface DatabaseService extends Service {
|
|||||||
@ConfigurationName("database")
|
@ConfigurationName("database")
|
||||||
public interface DatabaseConfiguration extends ServiceConfiguration {
|
public interface DatabaseConfiguration extends ServiceConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes several operations inside a single database transaction.
|
||||||
|
* <p>
|
||||||
|
* Queries inside a transaction applies to an <i>all-or-none</i> model. If
|
||||||
|
* any of the queries executed fails, none of them will be persisted to the
|
||||||
|
* database and no changes will be performed. Transactions are useful in
|
||||||
|
* maintaining data consistency.
|
||||||
|
* <p>
|
||||||
|
* <b>Important</b>: You should <b>never</b> call any async
|
||||||
|
* {@link DataAccessObject} within a transaction. Doing so, will make it be
|
||||||
|
* executed in <b>another transaction</b> and might even cause data
|
||||||
|
* corruption due to queries being executed in different transactions.
|
||||||
|
* <p>
|
||||||
|
* If you wish to execute an transaction asynchronously, see
|
||||||
|
* {@link #transactionAsync(TransactionExecutor)}.
|
||||||
|
*
|
||||||
|
* @param executor
|
||||||
|
* the executor implementation (normally an anonymous class)
|
||||||
|
* @return the number of affected rows
|
||||||
|
* @see DatabaseService#transactionAsync(TransactionExecutor)
|
||||||
|
*/
|
||||||
|
int transaction(TransactionExecutor executor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously executes several operations inside a single database
|
||||||
|
* transaction.
|
||||||
|
* <p>
|
||||||
|
* Queries inside a transaction applies to an<i>all-or-none</i> model. If
|
||||||
|
* any of the queries executed fails, none of them will be persisted to the
|
||||||
|
* database and no changes will be performed. Transactions are useful in
|
||||||
|
* maintaining data consistency.
|
||||||
|
*
|
||||||
|
* @param executor
|
||||||
|
* the executor implementation (normally an anonymous class)
|
||||||
|
* @return the number of affected rows
|
||||||
|
*/
|
||||||
|
AsyncFuture<Integer> transactionAsync(TransactionExecutor executor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class executes DAO operations inside an transaction. It is
|
||||||
|
* recommended to implement it in an anonymous class.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
public interface TransactionExecutor {
|
||||||
|
/**
|
||||||
|
* Perform operations inside the transaction.
|
||||||
|
*
|
||||||
|
* @return the number of affected rows
|
||||||
|
*/
|
||||||
|
int perform();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,22 +9,71 @@
|
|||||||
<xs:complexType name="ItemType">
|
<xs:complexType name="ItemType">
|
||||||
<xs:complexContent>
|
<xs:complexContent>
|
||||||
<xs:extension base="AbstractTemplateType">
|
<xs:extension base="AbstractTemplateType">
|
||||||
<xs:sequence>
|
<xs:all>
|
||||||
<xs:element name="weight" type="xs:int" />
|
<xs:element name="attributes">
|
||||||
<xs:element name="price" type="xs:int" />
|
<xs:complexType>
|
||||||
<xs:element name="icon" type="xs:string" minOccurs="0" />
|
<xs:sequence>
|
||||||
<xs:element name="effect" type="ItemEffectsType"
|
<xs:element name="cost">
|
||||||
minOccurs="0" />
|
<xs:complexType>
|
||||||
<xs:element name="stats" type="ItemStatsType" minOccurs="0" />
|
<xs:attribute name="adena" />
|
||||||
<xs:element name="material" type="ItemMaterialType" />
|
</xs:complexType>
|
||||||
<xs:element name="itemType" type="ItemEnumType"
|
</xs:element>
|
||||||
minOccurs="0" />
|
<xs:element name="equipment">
|
||||||
<xs:element name="weaponType" type="WeaponType"
|
<xs:complexType>
|
||||||
minOccurs="0" />
|
<xs:attribute name="part" />
|
||||||
<xs:element name="armorType" type="ArmorType" minOccurs="0" />
|
</xs:complexType>
|
||||||
</xs:sequence>
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="weigth" />
|
||||||
|
<xs:attribute name="type" />
|
||||||
|
<xs:attribute name="material" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="controller">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="defaultAction" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="effect">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="type" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element name="weapon">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="part" />
|
||||||
|
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="armor">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="cost">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="adena" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="equipment">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="part" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="weigth" />
|
||||||
|
<xs:attribute name="type" />
|
||||||
|
<xs:attribute name="material" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:all>
|
||||||
<xs:attribute name="id" type="xs:int" use="required" />
|
<xs:attribute name="id" type="xs:int" use="required" />
|
||||||
<xs:attribute name="name" type="xs:string" use="required" />
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="icon" type="xs:string"></xs:attribute>
|
||||||
</xs:extension>
|
</xs:extension>
|
||||||
</xs:complexContent>
|
</xs:complexContent>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -1,32 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- <template:item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -->
|
|
||||||
<!-- xsi:schemaLocation="http://schemas.l2jserver2.com/item ../item.xsd" -->
|
|
||||||
<!-- xmlns:template="http://schemas.l2jserver2.com/item" id="1" icon="icon.etc_adena_i00"> -->
|
|
||||||
<!-- <name>Short Sword</name> -->
|
|
||||||
<!-- <material>STEEL</material> -->
|
|
||||||
<!-- <effect type="IMMEDIATE" /> -->
|
|
||||||
<!-- <price>1</price> -->
|
|
||||||
<!-- <stats> -->
|
|
||||||
<!-- <physicalDamage> -->
|
|
||||||
<!-- <set order="128">510</set> -->
|
|
||||||
<!-- </physicalDamage> -->
|
|
||||||
<!-- <magicalDamage> -->
|
|
||||||
<!-- <set order="128">508</set> -->
|
|
||||||
<!-- </magicalDamage> -->
|
|
||||||
<!-- <criticalChance> -->
|
|
||||||
<!-- <set order="128">8</set> -->
|
|
||||||
<!-- </criticalChance> -->
|
|
||||||
<!-- <physicalAttackSpeed> -->
|
|
||||||
<!-- <set order="128">379</set> -->
|
|
||||||
<!-- </physicalAttackSpeed> -->
|
|
||||||
<!-- </stats> -->
|
|
||||||
<!-- </template:item> -->
|
|
||||||
<template:item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<template:item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://schemas.l2jserver2.com/item ../item.xsd"
|
xsi:schemaLocation="http://schemas.l2jserver2.com/item ../item.xsd"
|
||||||
xmlns:template="http://schemas.l2jserver2.com/item" id="1" name="Short sword">
|
xmlns:template="http://schemas.l2jserver2.com/item" id="1"
|
||||||
<weight>1</weight>
|
icon="icon.weapon_small_sword_i00" name="Short Sword">
|
||||||
<price>1</price>
|
<attributes weigth="1600" type="SWORD" material="STEEL">
|
||||||
<icon>icon.etc_adena_i00</icon>
|
<cost adena="590" />
|
||||||
<material>GOLD</material>
|
<equipment part="RIGHT_HAND" />
|
||||||
<!-- <effect type="IMMEDIATE" /> -->
|
</attributes>
|
||||||
|
<controller defaultAction="EQUIP" />
|
||||||
|
<effect type="IMMEDIATE" />
|
||||||
|
<weapon part="RIGHT_HAND">
|
||||||
|
<physicalDamage>
|
||||||
|
<set order="128">8</set>
|
||||||
|
<random order="127">10</random>
|
||||||
|
</physicalDamage>
|
||||||
|
<magicalDamage>
|
||||||
|
<set order="128">6</set>
|
||||||
|
</magicalDamage>
|
||||||
|
<criticalChance>
|
||||||
|
<set order="128">8</set>
|
||||||
|
</criticalChance>
|
||||||
|
<physicalAttackSpeed>
|
||||||
|
<set order="128">379</set>
|
||||||
|
</physicalAttackSpeed>
|
||||||
|
</weapon>
|
||||||
</template:item>
|
</template:item>
|
||||||
@@ -33,6 +33,7 @@ import com.l2jserver.model.world.NPC;
|
|||||||
import com.l2jserver.model.world.actor.event.ActorAttackHitEvent;
|
import com.l2jserver.model.world.actor.event.ActorAttackHitEvent;
|
||||||
import com.l2jserver.service.AbstractService;
|
import com.l2jserver.service.AbstractService;
|
||||||
import com.l2jserver.service.AbstractService.Depends;
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
import com.l2jserver.service.game.npc.NPCService;
|
import com.l2jserver.service.game.npc.NPCService;
|
||||||
@@ -99,7 +100,7 @@ public class AttackServiceImpl extends AbstractService implements AttackService
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
private class AttackCallable implements Callable<AttackHit> {
|
private class AttackCallable extends AbstractTask<AttackHit> {
|
||||||
/**
|
/**
|
||||||
* The attacker
|
* The attacker
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.l2jserver.service.game.npc;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -42,6 +41,7 @@ import com.l2jserver.model.world.npc.event.NPCDieEvent;
|
|||||||
import com.l2jserver.service.AbstractService;
|
import com.l2jserver.service.AbstractService;
|
||||||
import com.l2jserver.service.AbstractService.Depends;
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
import com.l2jserver.service.ServiceStartException;
|
import com.l2jserver.service.ServiceStartException;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
import com.l2jserver.service.database.DatabaseService;
|
import com.l2jserver.service.database.DatabaseService;
|
||||||
@@ -244,7 +244,7 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
|||||||
final double seconds = distance / npc.getTemplate().getRunSpeed();
|
final double seconds = distance / npc.getTemplate().getRunSpeed();
|
||||||
// TODO this is an dirty implementation!
|
// TODO this is an dirty implementation!
|
||||||
return threadService.async((int) (seconds * 1000),
|
return threadService.async((int) (seconds * 1000),
|
||||||
TimeUnit.MILLISECONDS, new Callable<Boolean>() {
|
TimeUnit.MILLISECONDS, new AbstractTask<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean call() throws Exception {
|
public Boolean call() throws Exception {
|
||||||
npc.setState(null);
|
npc.setState(null);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jserver.service.game.spawn;
|
package com.l2jserver.service.game.spawn;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -42,6 +41,7 @@ import com.l2jserver.model.world.npc.event.NPCUnspawnEvent;
|
|||||||
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
||||||
import com.l2jserver.service.AbstractService;
|
import com.l2jserver.service.AbstractService;
|
||||||
import com.l2jserver.service.AbstractService.Depends;
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
|
import com.l2jserver.service.core.threading.AbstractTask;
|
||||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
import com.l2jserver.service.game.world.WorldService;
|
import com.l2jserver.service.game.world.WorldService;
|
||||||
@@ -158,7 +158,7 @@ public class SpawnServiceImpl extends AbstractService implements SpawnService {
|
|||||||
log.debug("Scheduling spawn of {} at {} in {}ms", new Object[] {
|
log.debug("Scheduling spawn of {} at {} in {}ms", new Object[] {
|
||||||
object, point, unit.toMillis(time) });
|
object, point, unit.toMillis(time) });
|
||||||
|
|
||||||
return threadService.async(time, unit, new Callable<T>() {
|
return threadService.async(time, unit, new AbstractTask<T>() {
|
||||||
@Override
|
@Override
|
||||||
public T call() throws Exception {
|
public T call() throws Exception {
|
||||||
spawn(object, point);
|
spawn(object, point);
|
||||||
@@ -208,7 +208,7 @@ public class SpawnServiceImpl extends AbstractService implements SpawnService {
|
|||||||
log.debug("Scheduling unspawn of {} in {}ms", object,
|
log.debug("Scheduling unspawn of {} in {}ms", object,
|
||||||
unit.toMillis(time));
|
unit.toMillis(time));
|
||||||
|
|
||||||
return threadService.async(time, unit, new Callable<T>() {
|
return threadService.async(time, unit, new AbstractTask<T>() {
|
||||||
@Override
|
@Override
|
||||||
public T call() throws Exception {
|
public T call() throws Exception {
|
||||||
unspawn(object);
|
unspawn(object);
|
||||||
|
|||||||
Reference in New Issue
Block a user