Open source — не значит, что этим занимаются миллионы программистов старой школы, которые ничем не заняты. Мало того, open source даже не значит «бесплатно».
Хорошая идея поддерживать промисы. При этом отличная мысль — поддерживать их одновременно с колбеками, чтобы действительно каждый работал так как нравится.
Что касается проверки свободного места, то это уже в рамках критической секции нужно выполнять. Например, закрыли семафор, проверили место на диске, выполнили операцию, открыли семафор. Так второй поток будет заблокирован в момент, когда попытается закрыть семафор, если он уже закрыт, и будет разблокирован, когда семафор откроется. Таким образом проверка свободного места на диске будет выполняться в рамках одного потока.
Семафоры — самый простой способ решения проблем с доступом к критической секции, если абстрагироваться от Java.
За ними мониторы — примерно то же самое, только с очередями.
Ну и остальные структуры, которые описаны в статье для решения разного рода задач синхронизации потоков.
Расскажите, пожалуйста, а как у вас в проекте реализован протокол общения между устройством и сервером?
Я некоторое время назад тоже писал сервер на Netty для IoT и воодушевившись этой статьей реализовал примерно так:
Базовый класс
abstract public class Packet implements Serializable {
public static Packet read(ByteBuf buffer) throws IOException {
int id = buffer.readByte();
Packet packet = newPacket(id);
if (packet == null) throw new IOException("Bad packet ID: " + id);
packet.get(buffer);
return packet;
}
public static void write(Packet packet, ByteBuf buff) {
buff.writeByte(packet.getId());
packet.send(buff);
}
public static Packet newPacket(int id) {
try {
switch (id) {
case 1:
return PingPacket.class.newInstance();
case 2:
return AuthPacket.class.newInstance();
case 3:
return AuthResultPacket.class.newInstance();
case 4:
return SettingsPacket.class.newInstance();
case 5:
return TimePacket.class.newInstance();
case 6:
return ModulesPacket.class.newInstance();
case 7:
return UpdatePacket.class.newInstance();
case 8:
return SwitchStatePacket.class.newInstance();
}
} catch (Exception ignored) {}
return null;
}
public int getId() {
if (this instanceof PingPacket) {
return 1;
}
if (this instanceof AuthPacket) {
return 2;
}
if (this instanceof AuthResultPacket) {
return 3;
}
if (this instanceof SettingsPacket) {
return 4;
}
if (this instanceof TimePacket) {
return 5;
}
if (this instanceof ModulesPacket) {
return 6;
}
if (this instanceof UpdatePacket) {
return 7;
}
if (this instanceof SwitchStatePacket) {
return 8;
}
return 0;
}
abstract public void get(ByteBuf buffer);
abstract public void send(ByteBuf buffer);
/**
* Закрывать ли соединение по завершению отправки пакета
*/
public boolean closeConnection() {
return false;
}
/**************************************************************
* БАЗОВЫЕ МЕТОДЫ *
**************************************************************/
final protected void writeString(ByteBuf buffer, String string) {
buffer.writeShort(string.length());
for (int i = 0; i < string.length(); i++) {
buffer.writeChar(string.charAt(i));
}
}
final protected String readString(ByteBuf buffer) {
int length = buffer.readShort();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < length; i++) {
sb.append(buffer.readChar());
}
return sb.toString();
}
}
Класс пакета
public class ModulesPacket extends Packet {
private Set<Module> modules;
/**
* Не получаем от устройства
*/
@Override
public void get(ByteBuf buffer) {
}
@Override
public void send(ByteBuf buffer) {
buffer.writeShort(modules.size());
for (Module module : modules) {
buffer.writeLong(module.getId());
buffer.writeInt(module.getTypeId());
buffer.writeInt(module.getPin());
}
}
public ModulesPacket() {
}
public ModulesPacket(Set<Module> modules) {
this.modules = modules;
}
public Set<Module> getModules() {
return modules;
}
public void setModules(Set<Module> modules) {
this.modules = modules;
}
@Override
public String toString() {
return "ModulesPacket{" +
"modules=" + modules +
'}';
}
}
По началу исходники на Kotlin мне показались очень страшными непривычными, что пугало. Но повыполнял задания в песочнице и влюбился в этот язык. Это Java, только лучше! Как раз то, чего так сильно нехватало.
Vaadin, конечно, прекрасный фреймворк, но Вы не упомянули о том, что логика по отображению страницы формируется на серверной стороне. Так, например, если на клиенте при нажатии на кнопку нужно открыть pop-up, это вызовет запрос на сервер (тонкий клиент).
За удобство приходится платить. Поэтому vaadin не подходит для нагруженных решений (слишком много лишних запросов от клиента). Можно, конечно, разделить Java код на клиент и сервер, как в классическом GWT, сделать толстый клиент, но тогда его придётся разрабатывать отдельно и взаимодействовать с сервером через RPC.
Что касается liquidbase, мне больше нравится Flyway. В SQL миграциях проще разобраться на взгляд, чем в xml. А совместимость с несколькими СУБД редко бывает необходима.
Смешно.
Спасибо!
Спасибо!
За ними мониторы — примерно то же самое, только с очередями.
Ну и остальные структуры, которые описаны в статье для решения разного рода задач синхронизации потоков.
Семафор
Монитор
Расскажите, пожалуйста, а как у вас в проекте реализован протокол общения между устройством и сервером?
Я некоторое время назад тоже писал сервер на Netty для IoT и воодушевившись этой статьей реализовал примерно так:
Спасибо.
страшныминепривычными, что пугало. Но повыполнял задания в песочнице и влюбился в этот язык. Это Java, только лучше! Как раз то, чего так сильно нехватало.Кронштадт вперёд!))
Поправьте заголовок.
Не буду вдаваться в подробности, но прежде чем утверждать, хотя бы попробуйте: www.oracle.com/technetwork/java/javase/downloads/index.html
А как же Jelastic и все хостинг-компании, работающие с ним?
За удобство приходится платить. Поэтому vaadin не подходит для нагруженных решений (слишком много лишних запросов от клиента). Можно, конечно, разделить Java код на клиент и сервер, как в классическом GWT, сделать толстый клиент, но тогда его придётся разрабатывать отдельно и взаимодействовать с сервером через RPC.
Что касается liquidbase, мне больше нравится Flyway. В SQL миграциях проще разобраться на взгляд, чем в xml. А совместимость с несколькими СУБД редко бывает необходима.
Давно хотел попробовать написать плагин для идеи. Жду исходников, помогу с пулл-реквестами.