Examples: query, "exact match", wildcard*, wild?ard, wild*rd
Fuzzy search: cake~ (finds cakes, bake)
Term boost: "red velvet"^4, chocolate^2
Field grouping: tags:(+work -"fun-stuff")
Escape special characters +-&|!(){}[]^"~*?:\ - e.g. \+ \* \!
Range search: properties.timestamp:[1587729413488 TO *] (inclusive), properties.title:{A TO Z}(excluding A and Z)
Combinations: chocolate AND vanilla, chocolate OR vanilla, (chocolate OR vanilla) NOT "vanilla pudding"
Field search: properties.title:"The Title" AND text
Answered
Run multiple bots in the same instance

  1. Does BDK support creating multiple Bot connections from spring boot container? 
  2. Any concerns around using BDK instance per AsyncExecutor. i.e setting the AsyncExecutor per bot (SymphonyBdk) instance and performing authentication and datafeed long poling?
  3. Do you have any sample code around using BDK in multithreading environment?
  
  
Posted 2 years ago
Votes Newest

Answers


  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

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):

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

@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)

@Primary
@Component
@ConfigurationProperties(prefix = "bot1")
public class Bot1Config extends BdkConfig {}
@Component
@ConfigurationProperties(prefix = "bot2")
public class Bot2Config extends BdkConfig {}

Helper method to manually initialise SymphonyBdk instances

@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

@Component
public class BotService {
    public BotService(
        BotLoader botLoader,
        Bot1Config bot1Config,
        Bot2Config bot2Config
    ) throws Exception {
        botLoader.initBot(bot1Config);
        botLoader.initBot(bot2Config);
    }
}
  
  
Posted 2 years ago
Edited 2 years ago
Yong Sheng Tan
39 × 2 Administrator
9K Views
1 Answer
2 years ago
2 years ago
Tags