@@ -416,30 +416,32 @@ private static JobDescription jobDescription(int id, Row job,
416
416
}
417
417
418
418
@ Override
419
- public Optional < Job > createJobInGroup (String owner , String groupName ,
419
+ public Job createJobInGroup (String owner , String groupName ,
420
420
CreateDescriptor descriptor , String machineName , List <String > tags ,
421
- Duration keepaliveInterval , byte [] req ) {
421
+ Duration keepaliveInterval , byte [] req )
422
+ throws IllegalArgumentException {
422
423
return execute (conn -> {
423
424
int user = getUser (conn , owner ).orElseThrow (
424
425
() -> new RuntimeException ("no such user: " + owner ));
425
426
int group = selectGroup (conn , owner , groupName );
426
427
if (!quotaManager .mayCreateJob (group )) {
427
428
// No quota left
428
- return Optional .empty ();
429
+ throw new IllegalArgumentException (
430
+ "quota exceeded in group " + group );
429
431
}
430
432
431
- var m = selectMachine (conn , machineName , tags );
433
+ var m = selectMachine (conn , descriptor , machineName , tags );
432
434
if (!m .isPresent ()) {
433
- // Cannot find machine!
434
- return Optional .empty ();
435
+ throw new IllegalArgumentException (
436
+ "no machine available which matches allocation "
437
+ + "request" );
435
438
}
436
439
var machine = m .orElseThrow ();
437
440
438
441
var id = insertJob (conn , machine , user , group , keepaliveInterval ,
439
442
req );
440
443
if (!id .isPresent ()) {
441
- // Insert failed
442
- return Optional .empty ();
444
+ throw new RuntimeException ("failed to create job" );
443
445
}
444
446
int jobId = id .orElseThrow ();
445
447
@@ -512,12 +514,13 @@ public Integer board(CreateBoard b) {
512
514
machine .name , owner , numBoards );
513
515
514
516
allocator .scheduleAllocateNow ();
515
- return getJob (jobId , conn ).map (ji -> (Job ) ji );
517
+ return getJob (jobId , conn ).map (ji -> (Job ) ji ).orElseThrow (
518
+ () -> new RuntimeException ("Error creating job!" ));
516
519
});
517
520
}
518
521
519
522
@ Override
520
- public Optional < Job > createJob (String owner , CreateDescriptor descriptor ,
523
+ public Job createJob (String owner , CreateDescriptor descriptor ,
521
524
String machineName , List <String > tags , Duration keepaliveInterval ,
522
525
byte [] originalRequest ) {
523
526
return execute (conn -> createJobInGroup (
@@ -526,7 +529,7 @@ owner, getOnlyGroup(conn, owner), descriptor, machineName,
526
529
}
527
530
528
531
@ Override
529
- public Optional < Job > createJobInCollabSession (String owner ,
532
+ public Job createJobInCollabSession (String owner ,
530
533
String nmpiCollab , CreateDescriptor descriptor ,
531
534
String machineName , List <String > tags , Duration keepaliveInterval ,
532
535
byte [] originalRequest ) {
@@ -537,39 +540,30 @@ public Optional<Job> createJobInCollabSession(String owner,
537
540
var job = execute (conn -> createJobInGroup (
538
541
owner , nmpiCollab , descriptor , machineName ,
539
542
tags , keepaliveInterval , originalRequest ));
540
- // On failure to get job, just return; shouldn't happen as quota checked
541
- // earlier, but just in case!
542
- if (job .isEmpty ()) {
543
- return job ;
544
- }
545
543
546
- quotaManager .associateNMPISession (job .get (). getId (), session .getId (),
544
+ quotaManager .associateNMPISession (job .getId (), session .getId (),
547
545
quotaUnits );
548
546
549
547
// Return the job created
550
548
return job ;
551
549
}
552
550
553
551
@ Override
554
- public Optional < Job > createJobForNMPIJob (String owner , int nmpiJobId ,
552
+ public Job createJobForNMPIJob (String owner , int nmpiJobId ,
555
553
CreateDescriptor descriptor , String machineName , List <String > tags ,
556
554
Duration keepaliveInterval , byte [] originalRequest ) {
557
555
var collab = quotaManager .mayUseNMPIJob (owner , nmpiJobId );
558
556
if (collab .isEmpty ()) {
559
- return Optional .empty ();
557
+ throw new IllegalArgumentException ("User cannot create session in "
558
+ + "NMPI job" + nmpiJobId );
560
559
}
561
560
var quotaDetails = collab .get ();
562
561
563
562
var job = execute (conn -> createJobInGroup (
564
563
owner , quotaDetails .collabId , descriptor , machineName ,
565
564
tags , keepaliveInterval , originalRequest ));
566
- // On failure to get job, just return; shouldn't happen as quota checked
567
- // earlier, but just in case!
568
- if (job .isEmpty ()) {
569
- return job ;
570
- }
571
565
572
- quotaManager .associateNMPIJob (job .get (). getId (), nmpiJobId ,
566
+ quotaManager .associateNMPIJob (job .getId (), nmpiJobId ,
573
567
quotaDetails .quotaUnits );
574
568
575
569
// Return the job created
@@ -689,25 +683,74 @@ private static Optional<Integer> insertJob(Connection conn, MachineImpl m,
689
683
}
690
684
691
685
private Optional <MachineImpl > selectMachine (Connection conn ,
692
- String machineName , List <String > tags ) {
686
+ CreateDescriptor descriptor , String machineName ,
687
+ List <String > tags ) {
693
688
if (nonNull (machineName )) {
694
- return getMachine (machineName , false , conn );
695
- } else if (!tags .isEmpty ()) {
689
+ var m = getMachine (machineName , false , conn );
690
+ if (m .isPresent () && isAllocPossible (conn , descriptor , m .get ())) {
691
+ return m ;
692
+ }
693
+ return Optional .empty ();
694
+ }
695
+
696
+ if (!tags .isEmpty ()) {
696
697
for (var m : getMachines (conn , false ).values ()) {
697
698
var mi = (MachineImpl ) m ;
698
- if (mi .tags .containsAll (tags )) {
699
- /*
700
- * Originally, spalloc checked if allocation was possible;
701
- * we just assume that it is because there really isn't ever
702
- * going to be that many different machines on one service.
703
- */
699
+ if (mi .tags .containsAll (tags )
700
+ && isAllocPossible (conn , descriptor , mi )) {
704
701
return Optional .of (mi );
705
702
}
706
703
}
707
704
}
708
705
return Optional .empty ();
709
706
}
710
707
708
+ private boolean isAllocPossible (final Connection conn ,
709
+ final CreateDescriptor descriptor ,
710
+ final MachineImpl m ) {
711
+ return descriptor .visit (new CreateVisitor <Boolean >() {
712
+ @ Override
713
+ public Boolean numBoards (CreateNumBoards nb ) {
714
+ try (var getNBoards = conn .query (COUNT_FUNCTIONING_BOARDS )) {
715
+ var numBoards = getNBoards .call1 (integer ("c" ), m .id )
716
+ .orElseThrow ();
717
+ return numBoards >= nb .numBoards ;
718
+ }
719
+ }
720
+
721
+ @ Override
722
+ public Boolean dimensions (CreateDimensions d ) {
723
+ try (var checkPossible = conn .query (checkRectangle )) {
724
+ return checkPossible .call1 ((r ) -> true , d .width , d .height ,
725
+ m .id , d .maxDead ).isPresent ();
726
+ }
727
+ }
728
+
729
+ @ Override
730
+ public Boolean dimensionsAt (CreateDimensionsAt da ) {
731
+ try (var checkPossible = conn .query (checkRectangleAt )) {
732
+ int board = locateBoard (conn , m .name , da , true );
733
+ return checkPossible .call1 ((r ) -> true , board ,
734
+ da .width , da .height , m .id , da .maxDead ).isPresent ();
735
+ } catch (IllegalArgumentException e ) {
736
+ // This means the board doesn't exist on the given machine
737
+ return false ;
738
+ }
739
+ }
740
+
741
+ @ Override
742
+ public Boolean board (CreateBoard b ) {
743
+ try (var check = conn .query (CHECK_LOCATION )) {
744
+ int board = locateBoard (conn , m .name , b , false );
745
+ return check .call1 ((r ) -> true , m .id , board ).isPresent ();
746
+ } catch (IllegalArgumentException e ) {
747
+ // This means the board doesn't exist on the given machine
748
+ return false ;
749
+ }
750
+ }
751
+ });
752
+ }
753
+
711
754
@ Override
712
755
public void purgeDownCache () {
713
756
synchronized (this ) {
0 commit comments