コード例 #1
0
        public OfferProposal SaveOfferProposal(string receivingSubscriptionId, string sendingSubscriptionId, Offer offer, string demandId = null, Proposal.StateEnum state = Proposal.StateEnum.InitialEnum)
        {
            if (this.SubscriptionProposals.ContainsKey(receivingSubscriptionId) && this.Subscriptions[receivingSubscriptionId] is DemandSubscription)
            {
                var offerProposal = new OfferProposal()
                {
                    Id         = "" + Guid.NewGuid(),
                    InternalId = this.GetNextProposalInternalId(),
                    ReceivingSubscriptionId = receivingSubscriptionId,
                    SendingSubscriptionId   = sendingSubscriptionId,
                    DemandId = demandId,
                    Offer    = offer,
                    State    = state
                };

                this.SubscriptionProposals[receivingSubscriptionId].Add(offerProposal);
                this.OfferProposals[offerProposal.Id] = offerProposal;

                return(offerProposal);
            }
            else
            {
                throw new Exception($"Demand Subscription Id {receivingSubscriptionId} does not exist!");
            }
        }
コード例 #2
0
        public Agreement CreateAgreement(Demand demand, OfferProposal offerProposal)
        {
            if (this.Agreements.ContainsKey(offerProposal.Id))
            {
                throw new Exception($"Agreement Id {offerProposal.Id} already exists!");
            }

            var agreement = new Agreement()
            {
                Id     = offerProposal.Id,
                Offer  = offerProposal.Offer,
                Demand = demand,
                State  = AgreementState.New
            };

            this.Agreements[agreement.Id] = agreement;

            return(agreement);
        }
コード例 #3
0
        public Agreement CreateAgreement(DemandProposal demandProposal, OfferProposal offerProposal, DateTime validTo)
        {
            if (this.Agreements.ContainsKey(offerProposal.Id))
            {
                throw new Exception($"Agreement Id {offerProposal.Id} already exists!");
            }

            var agreement = new Agreement()
            {
                Id             = offerProposal.Id,
                OfferProposal  = offerProposal,
                DemandProposal = demandProposal,
                State          = AgreementState.Proposal,
                ValidTo        = validTo
            };

            this.Agreements[agreement.Id] = agreement;

            return(agreement);
        }
コード例 #4
0
        public async Task InMemoryActivityProcessor_Integration_SimplePositiveScenario()
        {
            // Test scenario

            var demand = new Demand()
            {
                Constraints = "", NodeId = "DummyRequestorNode1", Properties = new Dictionary <string, string>()
            };
            var offer = new OfferProposal()
            {
                DemandId   = "dummyDemandId",
                Id         = "DummyProposalId",
                InternalId = 1,
                Offer      = new Offer()
                {
                    Constraints = "",
                    NodeId      = "DummyProviderNode1",
                    Properties  = new Dictionary <string, string>()
                }
            };
            var agreement = this.AgreementRepository.CreateAgreement(demand, offer);

            // 1. Create Activity in a known, negotiated agreement

            var activity = this.RequestorProcessor.CreateActivity(agreement.Id);

            var provEvents = await this.ProviderProcessor.CollectActivityEventsAsync(offer.Offer.NodeId, 1000);

            // 2. Send a sample ExeScript command batch

            var batchId = this.RequestorProcessor.ExecAsync(activity.Id, new ExeScript()
            {
                Text = "DEPLOY\nSTART\n"
            });

            // 2.1. Simulate ExeScript execution on Provider side

            Task.Run(async() =>
            {
                bool isActivityDestroyed = false;

                do
                {
                    provEvents = await this.ProviderProcessor.CollectActivityEventsAsync(offer.Offer.NodeId, 1000);

                    foreach (var provEvent in provEvents)
                    {
                        switch (provEvent.EventType)
                        {
                        case ActivityProviderEvent.ActivityProviderEventType.Exec:
                            var commands = provEvent.ExeScript.Text.Split('\n');
                            foreach (var command in commands)
                            {
                                if (string.IsNullOrWhiteSpace(command))
                                {
                                    continue;
                                }

                                if (command.Contains("DEPLOY"))
                                {
                                    this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Deploying);
                                    Thread.Sleep(1000);
                                    this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Ready);
                                }

                                if (command.Contains("START"))
                                {
                                    this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Starting);
                                    Thread.Sleep(1000);
                                    this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Terminated);
                                }

                                activity = this.ActivityRepository.GetActivity(activity.Id);

                                this.ProviderProcessor.SendActivityExecResult(activity.Id, batchId, new ActivityExecResult()
                                {
                                    CurrentState = activity.State,
                                    Result       = ActivityExecResult.ActivityExecResultEnum.OK
                                });
                            }
                            break;

                        case ActivityProviderEvent.ActivityProviderEventType.DestroyActivity:
                            isActivityDestroyed = true;
                            break;
                        }
                    }
                }while (isActivityDestroyed != true);
            });


            // 2.2. Process the ExeScript results on Requestor side

            bool isActivityFinished = false;

            do
            {
                var reqEvents = await this.RequestorProcessor.GetExecBatchResultsAsync(batchId, 1000);

                foreach (var reqEvent in reqEvents)
                {
                    Assert.AreEqual(ActivityExecResult.ActivityExecResultEnum.OK, reqEvent.ExecResult.Result);

                    if (reqEvent.ExecResult.CurrentState == ActivityState.Terminated)
                    {
                        isActivityFinished = true;
                    }
                }
            }while (!isActivityFinished);

            // 3. Destroy Activity

            this.RequestorProcessor.DestroyActivity(activity.Id);
        }
コード例 #5
0
        public async Task <OfferProposal> DoSimpleOfferNegotiation(DemandSubscription demandSubscription, OfferSubscription offerSubscription, OfferProposal offerProposal)
        {
            // OK, we got an offer proposal, we can now send a direct Demand counterproposal

            var counterDemand = new Demand()
            {
                Constraints = @"(&" +
                              @"(golem.srv.comp.container.docker.image=golemfactory/ffmpeg)" +
                              @"(golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}>300)" +
                              @"(golem.com.payment.scheme=after)" +
                              @"(golem.usage.vector=[golem.usage.duration_sec])" +
                              @"(golem.com.pricing.model=linear)" +
                              @"(golem.com.pricing.model.linear.coeffs=*)" +
                                           //@"(golem.com.pricing.est{[30]}<125)" +
                              @")",
                NodeId     = "RequestorA", // must be assigned from the outside
                Properties = new Dictionary <string, string>()
            };

            var counterDemandProposal = RequestorProcessor.CreateDemandProposal(demandSubscription.Id, offerProposal.Id, counterDemand);

            // At this point, the Provider should be able to read the Demand Proposal on the Offer subscription

            var provEvents = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 1000, 10);

            Assert.IsTrue(provEvents.Any());
            Assert.AreEqual(counterDemandProposal.Id, provEvents.First().DemandProposal.Id);
            Assert.AreEqual(offerProposal.Id, provEvents.First().DemandProposal.OfferId);

            // ...if we call again - there should be no proposals, so a timeout is expected after 100ms
            var provEvents2 = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 100, 10);

            Assert.IsFalse(provEvents2.Any());

            // Now test the blocking logic of Collect - hang on Collect on Requestor side, while Provider sends counter-offer

            ICollection <MarketRequestorEvent> reqEvents2 = null;

            Task.Run(async() =>
            {
                reqEvents2 = await RequestorProcessor.CollectRequestorEventsAsync(demandSubscription.Id, 5000, 10);

                Assert.IsTrue(reqEvents2.Any());
            });

            // ...and prepare counter-offer with price

            var counterOffer = new Offer()
            {
                Constraints = "()",
                NodeId      = "ProviderB",
                Properties  = new Dictionary <string, string>()
                {
                    { "golem.srv.comp.container.docker.image", @"[""golemfactory/ffmpeg""]" },
                    { "golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}", @"723" },
                    { "golem.srv.comp.container.docker.benchmark{*}", null },
                    { "golem.inf.cpu.cores", @"4" },
                    { "golem.inf.cpu.threads", @"8" },
                    { "golem.inf.mem.gib", @"16" },
                    { "golem.inf.storage.gib", @"30" },
                    { "golem.usage.vector", @"[""golem.usage.duration_sec""]" },
                    { "golem.com.payment.scheme", @"""after""" },
                    { "golem.com.pricing.model", @"""linear""" },
                    { "golem.com.pricing.model.linear.coeffs", @"[0, 0.2]" },
                    { "golem.com.pricing.est{*}", null },
                }
            };

            var counterOfferProposal = ProviderProcessor.CreateOfferProposal(offerSubscription.Id, provEvents.First().DemandProposal.Id, counterOffer);

            Thread.Sleep(1000);

            Assert.IsTrue(reqEvents2.Any());
            Assert.AreEqual(counterDemandProposal.Id, reqEvents2.First().OfferProposal.DemandId);

            return(reqEvents2.First().OfferProposal);
        }