Run multiple bots in the same instance
Run multiple bots in the same instance
1. Yes, it does. This is more straightforward in projects that do not use the Spring integration since you have to explicitly name the configurations and create instances of `SymphonyBdk`. The Spring integration assumes the use of 1 primary bot, so a bit of explicit definition is required.
2. No concerns specifically around authentication or datafeed polling, other than both bots sharing the same compute resources. The one thing to note is that you cannot use the default datafeed configuration since both will attempt to cache their respective datafeed id's in the same `datafeed.id` file. So either override `datafeed.idFilePath` for at least one of them, or use Datafeed v2 which does not use a disk cache via `datafeed.version: v2`.
3. Providing both no-framework and Spring versions for reference. Using a simple hello slash command registration on 2 bots, but you can imagine potential confusion when this gets more complex.
#### No Framework
```java
public class BotApplication {
private static final Logger log = LoggerFactory.getLogger(BotApplication.class);
private SymphonyBdk initBdk(String config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath(config));
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
return bdk;
}
private Runnable getDatafeedTask(SymphonyBdk bdk) {
return () -> {
try {
bdk.datafeed().start();
} catch (Exception e) {
log.error("Exception", e);
}
};
}
public BotApplication() throws Exception {
SymphonyBdk bot1 = initBdk("/bot1config.yaml");
SymphonyBdk bot2 = initBdk("/bot2config.yaml");
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(getDatafeedTask(bot1));
pool.execute(getDatafeedTask(bot2));
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new BotApplication();
}
}
```
#### Spring Framework
In `application.yaml`, prefix multiple instance configurations with custom identifiers (`bot1`, `bot2` etc):
```yaml
bot1:
host: develop2.symphony.com
bot:
username: bot1
privateKey.path: rsa/bot1-privatekey.pem
datafeed.version: v2
bot2:
host: develop2.symphony.com
bot:
username: bot2
privateKey.path: rsa/bot2-privatekey.pem
datafeed.version: v2
```
Enabling Async to make `@Async` calls later
```java
@EnableAsync
@SpringBootApplication
public class BotApplication {
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
}
}
```
Loading a subset of the `application.yaml` config prefixed with `bot1`, `bot2` etc. Note that one of these classes needs to be annotated with `@Primary`, which will serve as the primary instance for which autowiring BDK components such as `MessageService` will be used. (This design pattern seems unlikely to be used as it adds to confusion but the `@Primary` annotation needs to be added to avoid a bean qualification exception on startup)
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
```
```java
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}
```
Helper method to manually initialise `SymphonyBdk` instances
```java
@Component
public class BotLoader {
@Async
public void initBot(BdkConfig config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(config);
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
bdk.datafeed().start();
}
}
```
Service component to maintain the multiple instances
```java
@Component
public class BotService {
public BotService(
BotLoader botLoader,
Bot1Config bot1Config,
Bot2Config bot2Config
) throws Exception {
botLoader.initBot(bot1Config);
botLoader.initBot(bot2Config);
}
}
```
1. Yes, it does. This is more straightforward in projects that do not use the Spring integration since you have to explicitly name the configurations and create instances of `SymphonyBdk`. The Spring integration assumes the use of 1 primary bot, so a bit of explicit definition is required.
2. No concerns specifically around authentication or datafeed polling, other than both bots sharing the same compute resources. The one thing to note is that you cannot use the default datafeed configuration since both will attempt to cache their respective datafeed id's in the same `datafeed.id` file. So either override `datafeed.idFilePath` for at least one of them, or use Datafeed v2 which does not use a disk cache via `datafeed.version: v2`.
3. Providing both no-framework and Spring versions for reference. Using a simple hello slash command registration on 2 bots, but you can imagine potential confusion when this gets more complex.
#### No Framework
```java
public class BotApplication {
private static final Logger log = LoggerFactory.getLogger(BotApplication.class);
private SymphonyBdk initBdk(String config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath(config));
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
return bdk;
}
private Runnable getDatafeedTask(SymphonyBdk bdk) {
return () -> {
try {
bdk.datafeed().start();
} catch (Exception e) {
log.error("Exception", e);
}
};
}
public BotApplication() throws Exception {
SymphonyBdk bot1 = initBdk("/bot1config.yaml");
SymphonyBdk bot2 = initBdk("/bot2config.yaml");
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(getDatafeedTask(bot1));
pool.execute(getDatafeedTask(bot2));
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new BotApplication();
}
}
```
#### Spring Framework
In `application.yaml`, prefix multiple instance configurations with custom identifiers:
```yaml
bot1:
host: develop2.symphony.com
bot:
username: bot1
privateKey.path: rsa/bot1-privatekey.pem
datafeed.version: v2
bot2:
host: develop2.symphony.com
bot:
username: bot2
privateKey.path: rsa/bot2-privatekey.pem
datafeed.version: v2
```
Enabling Async to make @Async calls later
```java
@EnableAsync
@SpringBootApplication
public class BotApplication {
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
}
}
```
Loading a subset of the application.yaml class prefixed with bot1 / bot2 etc. Note that one of these classes needs to be annotated with `@Primary`, which will serve as the primary instance for which autowiring BDK components such as `MessageService` will be used. (This design pattern seems unlikely to be used as it adds to confusion but the `@Primary` annotation needs to be added to avoid a bean qualification exception on startup)
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
```
```java
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}
```
Helper method to manually initialise `SymphonyBdk` instances
```java
@Component
public class BotLoader {
@Async
public void initBot(BdkConfig config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(config);
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
bdk.datafeed().start();
}
}
```
Service component to maintain the multiple instances
```java
@Component
public class BotService {
public BotService(
BotLoader botLoader,
Bot1Config bot1Config,
Bot2Config bot2Config
) throws Exception {
botLoader.initBot(bot1Config);
botLoader.initBot(bot2Config);
}
}
```
Run multiple bots in the same instance
Run multiple bots in the same instance
1. Yes, it does. This is more straightforward in projects that do not use the Spring integration since you have to explicitly name the configurations and create instances of `SymphonyBdk`. The Spring integration assumes the use of 1 primary bot, so a bit of explicit definition is required.
2. No concerns specifically around authentication or datafeed polling, other than both bots sharing the same compute resources. The one thing to note is that you cannot use the default datafeed configuration since both will attempt to cache their respective datafeed id's in the same `datafeed.id` file. So either override `datafeed.idFilePath` for at least one of them, or use Datafeed v2 which does not use a disk cache via `datafeed.version: v2`.
3. Providing both no-framework and Spring versions for reference. Using a simple hello slash command registration on 2 bots, but you can imagine potential confusion when this gets more complex.
#### No Framework
```java
public class BotApplication {
private static final Logger log = LoggerFactory.getLogger(BotApplication.class);
private SymphonyBdk initBdk(String config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath(config));
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
return bdk;
}
private Runnable getDatafeedTask(SymphonyBdk bdk) {
return () -> {
try {
bdk.datafeed().start();
} catch (Exception e) {
log.error("Exception", e);
}
};
}
public BotApplication() throws Exception {
SymphonyBdk bot1 = initBdk("/bot1config.yaml");
SymphonyBdk bot2 = initBdk("/bot2config.yaml");
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(getDatafeedTask(bot1));
pool.execute(getDatafeedTask(bot2));
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new BotApplication();
}
}
```
#### Spring Framework
In `application.yaml`, prefix multiple instance configurations with custom identifiers:
```yaml
bot1:
host: develop2.symphony.com
bot:
username: bot1
privateKey.path: rsa/bot1-privatekey.pem
datafeed.version: v2
bot2:
host: develop2.symphony.com
bot:
username: bot2
privateKey.path: rsa/bot2-privatekey.pem
datafeed.version: v2
```
Enabling Async to make @Async calls later
```java
@EnableAsync
@SpringBootApplication
public class BotApplication {
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
}
}
```
Loading a subset of the application.yaml class prefixed with bot1 / bot2 etc. Note that one of these classes needs to be annotated with `@Primary`, which will serve as the primary instance for which autowiring BDK components such as `MessageService` will be used. (This design pattern seems unlikely to be used as it adds to confusion but the `@Primary` annotation needs to be added to avoid a bean qualification exception on startup)
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
```
```java
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}
```
Helper method to manually initialise `SymphonyBdk` instances
```java
@Component
public class BotLoader {
@Async
public void initBot(BdkConfig config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(config);
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
bdk.datafeed().start();
}
}
```
Service component to maintain the multiple instances
```java
@Component
public class BotService {
public BotService(
BotLoader botLoader,
Bot1Config bot1Config,
Bot2Config bot2Config
) throws Exception {
botLoader.initBot(bot1Config);
botLoader.initBot(bot2Config);
}
}
```
1. Yes, it does. This is more straightforward in projects that do not use the Spring integration since you have to explicitly name the configurations and create instances of `SymphonyBdk`. The Spring integration assumes the use of 1 primary bot, so a bit of explicit definition is required.
2. No concerns specifically around authentication or datafeed polling, other than both bots sharing the same compute resources. The one thing to note is that you cannot use the default datafeed configuration since both will attempt to cache their respective datafeed id's in the same `datafeed.id` file. So either override `datafeed.idFilePath` for at least one of them, or use Datafeed v2 which does not use a disk cache via `datafeed.version: v2`.
3. Providing both no-framework and Spring versions for reference. Using a simple hello slash command registration on 2 bots, but you can imagine potential confusion when this gets more complex.
#### No Framework
```java
public class BotApplication {
private static final Logger log = LoggerFactory.getLogger(BotApplication.class);
private SymphonyBdk initBdk(String config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath(config));
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
return bdk;
}
private Runnable getDatafeedTask(SymphonyBdk bdk) {
return () -> {
try {
bdk.datafeed().start();
} catch (Exception e) {
log.error("Exception", e);
}
};
}
public BotApplication() throws Exception {
SymphonyBdk bot1 = initBdk("/bot1config.yaml");
SymphonyBdk bot2 = initBdk("/bot2config.yaml");
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(getDatafeedTask(bot1));
pool.execute(getDatafeedTask(bot2));
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new BotApplication();
}
}
```
#### Spring Framework
Prefix multiple instance configurations with custom identifiers:
```yaml
bot1:
host: develop2.symphony.com
bot:
username: bot1
privateKey.path: rsa/bot1-privatekey.pem
datafeed.version: v2
bot2:
host: develop2.symphony.com
bot:
username: bot2
privateKey.path: rsa/bot2-privatekey.pem
datafeed.version: v2
```
Enabling Async to make @Async calls later
```java
@EnableAsync
@SpringBootApplication
public class BotApplication {
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
}
}
```
Loading a subset of the application.yaml class prefixed with bot1 / bot2 etc
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
```
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}
```
Helper method to manually initialise `SymphonyBdk` instances
```java
@Component
public class BotLoader {
@Async
public void initBot(BdkConfig config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(config);
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
bdk.datafeed().start();
}
}
```
Service component to maintain the multiple instances
```java
@Component
public class BotService {
public BotService(
BotLoader botLoader,
Bot1Config bot1Config,
Bot2Config bot2Config
) throws Exception {
botLoader.initBot(bot1Config);
botLoader.initBot(bot2Config);
}
}
```
Run multiple bots in the same instance
1. Yes, it does. This is more straightforward in projects that do not use the Spring integration since you have to explicitly name the configurations and create instances of `SymphonyBdk`. The Spring integration assumes the use of 1 primary bot, so a bit of explicit definition is required.
2. No concerns specifically around authentication or datafeed polling, other than both bots sharing the same compute resources. The one thing to note is that you cannot use the default datafeed configuration since both will attempt to cache their respective datafeed id's in the same `datafeed.id` file. So either override `datafeed.idFilePath` for at least one of them, or use Datafeed v2 which does not use a disk cache via `datafeed.version: v2`.
3. Providing both no-framework and Spring versions for reference. Using a simple hello slash command registration on 2 bots, but you can imagine potential confusion when this gets more complex.
#### No Framework
```java
public class BotApplication {
private static final Logger log = LoggerFactory.getLogger(BotApplication.class);
private SymphonyBdk initBdk(String config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath(config));
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
return bdk;
}
private Runnable getDatafeedTask(SymphonyBdk bdk) {
return () -> {
try {
bdk.datafeed().start();
} catch (Exception e) {
log.error("Exception", e);
}
};
}
public BotApplication() throws Exception {
SymphonyBdk bot1 = initBdk("/bot1config.yaml");
SymphonyBdk bot2 = initBdk("/bot2config.yaml");
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(getDatafeedTask(bot1));
pool.execute(getDatafeedTask(bot2));
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new BotApplication();
}
}
```
#### Spring Framework
Prefix multiple instance configurations with custom identifiers:
```yaml
bot1:
host: develop2.symphony.com
bot:
username: bot1
privateKey.path: rsa/bot1-privatekey.pem
datafeed.version: v2
bot2:
host: develop2.symphony.com
bot:
username: bot2
privateKey.path: rsa/bot2-privatekey.pem
datafeed.version: v2
```
Enabling Async to make @Async calls later
```java
@EnableAsync
@SpringBootApplication
public class BotApplication {
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
}
}
```
Loading a subset of the application.yaml class prefixed with bot1 / bot2 etc
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
```
```java
@Primary
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}
```
Helper method to manually initialise `SymphonyBdk` instances
```java
@Component
public class BotLoader {
@Async
public void initBot(BdkConfig config) throws Exception {
SymphonyBdk bdk = new SymphonyBdk(config);
bdk.activities().register(slash("/hello", false,
context -> bdk.messages().send(context.getStreamId(), "hello")));
bdk.datafeed().start();
}
}
```
Service component to maintain the multiple instances
```java
@Component
public class BotService {
public BotService(
BotLoader botLoader,
Bot1Config bot1Config,
Bot2Config bot2Config
) throws Exception {
botLoader.initBot(bot1Config);
botLoader.initBot(bot2Config);
}
}
```